I'm new to unity and I've developing a simple 2d game.
at scoreboard scene i've managed to save scores and display them on a scrollview. when i run it in unity it works fine but when i build and run in my android phone the scrollview looks a bit bigger and text ui (added by script) look very small.
Here is the code to display scores in content game object in scrollview :
void Start () {
if (PlayerPrefs.HasKey (0 + "HScore")) {
float y = -30;
for (int i = 0; i < 10; i++) {
if (PlayerPrefs.GetInt (i + "HScore") == 0) {
break;
}
GameObject textobj = new GameObject (i + "HScoreName", typeof(RectTransform));
GameObject textobj2 = new GameObject (i + "HScore", typeof(RectTransform));
Text name = textobj.AddComponent<Text> ();
Text score = textobj2.AddComponent<Text> ();
GameObject lineObj = new GameObject ("Line", typeof(RectTransform));
Image l = lineObj.AddComponent<Image> ();
l.color = Color.white;
lineObj.transform.localScale = new Vector3 (500, 0.01f, 1);
name.text = "#" + (i + 1) + "- " + PlayerPrefs.GetString (i + "HScoreName");
score.text = PlayerPrefs.GetInt (i + "HScore").ToString ();
name.color = Color.white;
score.color = Color.white;
name.alignment = TextAnchor.MiddleLeft;
score.alignment = TextAnchor.MiddleLeft;
name.horizontalOverflow = HorizontalWrapMode.Overflow;
name.font = Resources.GetBuiltinResource<Font> ("Arial.ttf");
score.font = Resources.GetBuiltinResource<Font> ("Arial.ttf");
name.fontSize = 15;
score.fontSize = 15;
score.fontStyle = FontStyle.Bold;
textobj.transform.position = content.transform.position + new Vector3 (70, y, 0);
textobj.transform.SetParent (content.transform);
textobj2.transform.position = content.transform.position + new Vector3 (180, y, 0);
textobj2.transform.SetParent (content.transform);
lineObj.transform.position = content.transform.position + new Vector3 (60, y - 25, 0);
lineObj.transform.SetParent (content.transform);
y = y - 50;
}
}
}
is there anything missing in this script to keep text fit with screen?
You are using flat numbers, what you need s a percentage of Screen.width and Screen.height
For example if you are running in a phone with resolution 150x150 for example, if you want it in position 5, 5 you write this
transform.position = (5 / 100) * 150, it will set your object at 5 PERCENT from the bottom left edge.
There is a component - Canvas Scaler on the Canvas. Try to to change UI Scale Mode - Scale with Screen Size - it must be on the Canvas. And also you can play with Math value
Try to change UI Scale Mode - Scale with Screen Size - it must be on the Canvas.
Related
I am using Unity 2020.3.4f1 to create a 2D game for mobile.
I created a map builder for the game.
When I hit play, it makes a bunch of 'maps' that are saved as json files. The longer the game plays seems to result in extremely slow frame rates (200fps -> 2 fps) based on the stats menu while the game is running.
The strange thing is if I go to the "Scene" tab and left click on a sprite the fps instantly jumps back up again.
Screenshots
The problem seems related to taking screenshots within Unity.
The big bulge happens & only resets when I un-pause the game.
Questions
Why would the frame rates drop considerably over time the longer the game is running?
Why would the frame rate jump back up after selecting a sprite in the "Scene" tab?
What happens in Unity when selecting a sprite in the "Scene" tab? Is there a garbage collection method?
Script:
private void Awake()
{
myCamera = gameObject.GetComponent<Camera>();
instance = this;
width = 500;
height = 500;
}
private void OnPostRender()
{
if(takeScreenShotOnNextFrame)
{
takeScreenShotOnNextFrame = false;
RenderTexture renderTexture = myCamera.targetTexture;
Texture2D renderResult = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
Rect rect = new Rect(0, 0, renderTexture.width, renderTexture.height);
renderResult.ReadPixels(rect, 0, 0);
float myValue = 0;
float totalPixels = renderResult.width * renderResult.height;
for (int i = 0; i < renderResult.width; i++)
{
for (int j = 0; j < renderResult.height; j++)
{
Color myColor = renderResult.GetPixel(i, j);
myValue += myColor.r;
//Debug.Log("Pixel (" + i + "," + j + "): " + myColor.r);
}
}
occlusion = ((myValue / totalPixels) * 100);
byte[] byteArray = renderResult.EncodeToPNG();
System.IO.File.WriteAllBytes(Application.dataPath + "/Resources/ScreenShots/CameraScreenshot.png", byteArray);
// Cleanup
RenderTexture.ReleaseTemporary(renderTexture);
myCamera.targetTexture = null;
renderResult = null;
}
}
private void TakeScreenshot(int screenWidth, int screenHeight)
{
width = screenWidth;
height = screenHeight;
if(myCamera.targetTexture != null)
{
RenderTexture.ReleaseTemporary(myCamera.targetTexture);
//Debug.Log("Camera target texture null: " + myCamera.targetTexture == null);
}
myCamera.targetTexture = RenderTexture.GetTemporary(width, height, 16);
takeScreenShotOnNextFrame = true;
}
public static void TakeScreenshot_Static(int screenWidth, int screenHeight)
{
instance.TakeScreenshot(screenWidth, screenHeight);
}
}
I'm using Editor Window maybe that's the problem ?
The idea is when connecting two nodes is also to make an arrow at the end position that will show the connecting flow direction.
In the screenshot when I'm connecting two nodes for example Window 0 to Window 1
So there should be an arrow at the end of the line near Window 1 showing indicating that Window 0 is connected to Window 1 so the flow is from Window 0 to Window 1.
But it's not drawing any ArrowHandleCap.
I don't mind to draw another simple white arrow at the end position but it's not working at all for now. Not drawing an arrow at all.
This is my Editor Window code :
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.Graphs;
using UnityEngine.UI;
public class NodeEditor : EditorWindow
{
List<Rect> windows = new List<Rect>();
List<int> windowsToAttach = new List<int>();
List<int> attachedWindows = new List<int>();
int tab = 0;
float size = 10f;
[MenuItem("Window/Node editor")]
static void ShowEditor()
{
const int width = 600;
const int height = 600;
var x = (Screen.currentResolution.width - width) / 2;
var y = (Screen.currentResolution.height - height) / 2;
GetWindow<NodeEditor>().position = new Rect(x, y, width, height);
}
void OnGUI()
{
Rect graphPosition = new Rect(0f, 0f, position.width, position.height);
GraphBackground.DrawGraphBackground(graphPosition, graphPosition);
int selected = 0;
string[] options = new string[]
{
"Option1", "Option2", "Option3",
};
selected = EditorGUILayout.Popup("Label", selected, options);
if (windowsToAttach.Count == 2)
{
attachedWindows.Add(windowsToAttach[0]);
attachedWindows.Add(windowsToAttach[1]);
windowsToAttach = new List<int>();
}
if (attachedWindows.Count >= 2)
{
for (int i = 0; i < attachedWindows.Count; i += 2)
{
DrawNodeCurve(windows[attachedWindows[i]], windows[attachedWindows[i + 1]]);
}
}
BeginWindows();
if (GUILayout.Button("Create Node"))
{
windows.Add(new Rect(10, 10, 200, 40));
}
for (int i = 0; i < windows.Count; i++)
{
windows[i] = GUI.Window(i, windows[i], DrawNodeWindow, "Window " + i);
}
EndWindows();
}
void DrawNodeWindow(int id)
{
if (GUILayout.Button("Attach"))
{
windowsToAttach.Add(id);
}
GUI.DragWindow();
}
void DrawNodeCurve(Rect start, Rect end)
{
Vector3 startPos = new Vector3(start.x + start.width, start.y + start.height / 2, 0);
Vector3 endPos = new Vector3(end.x, end.y + end.height / 2, 0);
Vector3 startTan = startPos + Vector3.right * 50;
Vector3 endTan = endPos + Vector3.left * 50;
Color shadowCol = new Color(255, 255, 255);
for (int i = 0; i < 3; i++)
{// Draw a shadow
//Handles.DrawBezier(startPos, endPos, startTan, endTan, shadowCol, null, (i + 1) * 5);
}
Handles.DrawBezier(startPos, endPos, startTan, endTan, Color.white, null, 5);
Handles.color = Handles.xAxisColor;
Handles.ArrowHandleCap(0, endPos, Quaternion.LookRotation(Vector3.right), size, EventType.Repaint);
}
}
The problem is that the arrow is always behind the e.g. Window 0 since you call DrawNodeWindow always after DrawNodeCurve.
It happens because the arrow is always drawen starting from the endPos to the right direction with length = size so you always overlay it with the window later ... you have to change
// move your endpos to the left by size
var endPos = new Vector3(end.x - size, end.y + end.height / 2 , 0);
in order to have it start size pixels left before the actual end.x position.
However, as you can see it is still really small since it usually is used to display the arrow in 3D space - not using Pixel coordinates .. you might have to tweak arround or use something completely different.
How about e.g. simply using a GUI.DrawTexture instead with a given Arrow sprite?
// assign this as default reference via the Inspector for that script
[SerializeField] private Texture2D aTexture;
// ...
// since the drawTexture needs a rect which is not centered on the height anymore
// you have to use endPos.y - size / 2 for the Y start position of the texture
GUI.DrawTexture(new Rect(endPos.x, endPos.y - size / 2, size, size), aTexture, ScaleMode.StretchToFill);
like mentioned in the comment for all serialized fields in Unity you can already reference default assets for the script itself (in contrary to doing it for each instance like for MonoBehaviours) so with the NodeEditor script selected simply reference a downloaded arrow texture
If using a white arrow as texture you could then still change its color using
var color = GUI.color;
GUI.color = Handles.xAxisColor;
GUI.DrawTexture(new Rect(endPos.x, endPos.y - size / 2, size, size), aTexture, ScaleMode.StretchToFill);
GUI.color = color;
Result
P.S.: Arrow icon usedfor the example: https://iconsplace.com/red-icons/arrow-icon-14 you can already change the color directly on that page before downloading the icon ;)
If the grid is 10x10 or 23x7 it's working fine but when the grid have 1.5 spaces between the cubes the directions sometimes are wrong.
This is the grid script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GridGenerator : MonoBehaviour
{
public GameObject gridBlock;
public int gridWidth = 10;
public int gridHeight = 10;
public GameObject[] allBlocks;
private GameObject[] wallsParents = new GameObject[4];
void Start()
{
wallsParents[0] = GameObject.Find("Top Wall");
wallsParents[1] = GameObject.Find("Left Wall");
wallsParents[2] = GameObject.Find("Right Wall");
wallsParents[3] = GameObject.Find("Bottom Wall");
GenerateGrid();
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
var findpath = GetComponent<PathFinder>();
findpath.FindPath();
}
public void AutoGenerateGrid()
{
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
for (int i = 0; i < allBlocks.Length; i++)
{
DestroyImmediate(allBlocks[i]);
}
var end = GameObject.FindGameObjectWithTag("End");
DestroyImmediate(end);
GenerateGrid();
allBlocks = GameObject.FindGameObjectsWithTag("Blocks");
var findpath = GetComponent<PathFinder>();
findpath.FindPath();
}
public void GenerateGrid()
{
for (int x = 0; x < gridWidth; x++)
{
for (int z = 0; z < gridHeight; z++)
{
GameObject block = Instantiate(gridBlock, Vector3.zero, gridBlock.transform.rotation) as GameObject;
block.transform.parent = transform;
block.transform.name = "Block";
block.transform.tag = "Blocks";
block.transform.localPosition = new Vector3(x * 1.5f, 0, z * 1.5f);
block.GetComponent<Renderer>().material.color = new Color(241, 255, 0, 255);
if (x == 0)//TOP
{
block.transform.parent = wallsParents[0].transform;
block.transform.name = "TopWall";
block.transform.tag = "Blocks";
}
else if (z == 0)//LEFT
{
block.transform.parent = wallsParents[1].transform;
block.transform.name = "LeftWall";
block.transform.tag = "Blocks";
}
else if (z == gridHeight - 1)//RIGHT
{
block.transform.parent = wallsParents[2].transform;
block.transform.name = "RightWall";
block.transform.tag = "Blocks";
}
else if (x == gridWidth - 1)//BOTTOM
{
block.transform.parent = wallsParents[3].transform;
block.transform.name = "BottomWall";
block.transform.tag = "Blocks";
}
}
}
}
}
On this line i'm adding the spaces between the cubes:
block.transform.localPosition = new Vector3(x * 1.5f, 0, z * 1.5f);
Then in another script i'm trying to find what directions next are possible to move to.
private void Directions()
{
GridGenerator gridgenerator = GetComponent<GridGenerator>();
Vector3 playerPosition;
playerPosition = player.localPosition;
if (playerPosition.x > 0)
{
// can go left
possibleDirections[0] = "Can go left";
}
else
{
possibleDirections[0] = "Can't go left";
}
if (playerPosition.x + 1 < gridgenerator.gridWidth * 1.5f)
{
// can go right
possibleDirections[1] = "Can go right";
}
else
{
possibleDirections[1] = "Can't go right";
}
if (playerPosition.z > 0)
{
// can go backward
possibleDirections[2] = "Can go backward";
}
else
{
possibleDirections[2] = "Can't go backward";
}
if (playerPosition.z + 1 < gridgenerator.gridHeight * 1.5f)
{
// can go backward
possibleDirections[3] = "Can go forward";
}
else
{
possibleDirections[3] = "Can't go forward";
}
}
possibleDirections is array string type
When the grid size is 10x10 without spaces between cubes this two lines:
if (playerPosition.x + 1 < gridgenerator.gridWidth * 1.5f)
if (playerPosition.z + 1 < gridgenerator.gridHeight * 1.5f)
Was:
if (playerPosition.x + 1 < gridgenerator.gridWidth)
if (playerPosition.z + 1 < gridgenerator.gridHeight)
But when i added the spaces between the cubes i tried to add to the gridgenerator.gridWidth and gridgenerator.gridHeight the * 1.5
But it didn't work so i tried also:
if (playerPosition.x + 1 < gridgenerator.gridWidth * (1 + 1.5))
if (playerPosition.z + 1 < gridgenerator.gridHeight * (1 + 1.5))
1 is the cube width and 1.5 is the space. But this is not working good either.
In the screenshot the player is in the top left corner facing up(forward)
He can't move forward but in the inspector it says "Can go forward" And should be "Can't go forward"
It only happens when there are spaces between the cubes.
This line is wrong:
if (playerPosition.x + 1 < gridgenerator.gridWidth * 1.5f)
Your gridWidth variable stores the number of cubes, not their collective spacing. You have 10 cubes representing move spaces, determining the out-of-bounds this value should remain constant (it's still only 10 cubes, even if they're spaced with a half-block worth of space between them).
You need to convert from the player's scene location (transform.position.x) to a board space location (likely dividing by the same multiplier used to space the cubes out).
Alternatively, the "this makes my soul cry" solution of doing this:
if (playerPosition.x + 1.5f < gridgenerator.gridWidth * 1.5f)
Because the next cube is 1.5 scene units away, not 1. And this makes my soul cry because it makes your code full of hard-coded 1.5f multipliers and offsets rather than keeping such things to a single, fixed, constant value stored Elsewhere and used sparingly.
Related:
possibleDirections[0] = "Can go left";
Why are you using stringly typed things? There are values called booleans for a reason...
So I have a script that shoots an arrow when you click and drag, kinda like Angry Birds.
I want it to work with the 2D RigidBody and 2D collider but when I change the rigidbody.AddForce to rigidbody2D.AddForce, It doesn't work.
How can I fix this to work for 2D?
I also want the arrow to rotate in 2D space either up or down depending on where mouse is pulled back. When I try the mouse look script, it rotates it in the z axis (I think) and distorts the arrow. Any easy solution to fix this??
Thanks guys. I'm new to game making and I've been trying to figure this stuff out for like the last 10 hours. I need some pros to help!
Thanks!!!
Heres my script
using UnityEngine;
using System.Collections;
public class DragShotMover2 : MonoBehaviour {
public float maxDragLength = 2; // this is the base magnitude and the maximum length of the line drawn in the user interface
public float maxMultiplier = 5; // multiply the line length by this to allow for higher force values to be represented by shorter lines
public Vector3 dragPlaneNormal = Vector3.up; // a vector describing the orientation of the drag plan relative to world-space but centered on the target
public SnapDir snapDirection = SnapDir.away; // force is applied either toward or away from the mouse on release
public ForceMode forceTypeToApply = ForceMode.VelocityChange;
public bool overrideVelocity = true; // cancel the existing velocity before applying the new force
public bool pauseOnDrag = true; // causes the simulation to pause when the object is clicked and unpause when released
public Color noForceColor = Color.yellow; // color of the visualization helpers at force 0
public Color maxForceColor = Color.red; // color of the visualization helpers at maximum force
public enum SnapDir {toward, away}
private Vector3 forceVector;
private float magPercent = 0;
private bool mouseDragging = false;
private Vector3 mousePos3D;
private float dragDistance;
private Plane dragPlane;
private Ray mouseRay;
private GameObject dragZone;
private string shaderString = "Transparent/Diffuse";
private Material dzMat;
void Start (){
Color currentColor = noForceColor;
dzMat = new Material(Shader.Find(shaderString));
// create the dragzone visual helper
dragZone = new GameObject("dragZone_" + gameObject.name);
dragZone.AddComponent<MeshFilter>().mesh = MakeDiscMeshBrute(maxDragLength/4);
//dragZone.GetComponent.MeshFilter.
dragZone.AddComponent<MeshRenderer>();
dragZone.renderer.enabled = false;
dragZone.name = "dragZone_" + gameObject.name;
dragZone.transform.localScale = new Vector3(maxDragLength*2, 0.025f, maxDragLength*2);
dragZone.renderer.material = dzMat;
dragZone.renderer.material.color = currentColor * new Color(1,1,1,0.2f);
// create the dragplane
dragPlane = new Plane(dragPlaneNormal, transform.position);
// orient the drag plane
if (dragPlaneNormal != Vector3.zero) {
dragZone.transform.rotation = Quaternion.LookRotation(dragPlaneNormal) * new Quaternion(1, 0, 0, 1);
}
else Debug.LogError("Drag plane normal cannot be equal to Vector3.zero.");
//update the position of the dragzone
dragZone.transform.position = transform.position;
}
void OnMouseDown (){
mouseDragging = true;
if (pauseOnDrag) {
// pause the simulation
Time.timeScale = 0;
}
// update the dragplane
dragPlane = new Plane(dragPlaneNormal, transform.position);
// orient the drag plane
if (dragPlaneNormal != Vector3.zero) {
dragZone.transform.rotation = Quaternion.LookRotation(dragPlaneNormal) * new Quaternion(1, 0, 0, 1);
}
else Debug.LogError("Drag plane normal cannot be equal to Vector3.zero.");
//update the position of the dragzone
dragZone.transform.position = transform.position;
dragZone.renderer.enabled = true;
}
void OnMouseDrag (){
Color currentColor = noForceColor;
// update the plane if the target object has left it
if (dragPlane.GetDistanceToPoint(transform.position) != 0) {
// update dragplane by constructing a new one -- I should check this with a profiler
dragPlane = new Plane(dragPlaneNormal, transform.position);
}
// create a ray from the camera, through the mouse position in 3D space
mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
// if mouseRay intersects with dragPlane
float intersectDist = 0.0f;
if (dragPlane.Raycast(mouseRay, out intersectDist)) {
// update the world space point for the mouse position on the dragPlane
mousePos3D = mouseRay.GetPoint(intersectDist);
// calculate the distance between the 3d mouse position and the object position
dragDistance = Mathf.Clamp((mousePos3D - transform.position).magnitude, 0, maxDragLength);
// calculate the force vector
if (dragDistance*maxMultiplier < 1) dragDistance = 0; // this is to allow for a "no move" buffer close to the object
forceVector = mousePos3D - transform.position;
forceVector.Normalize();
forceVector *= dragDistance * maxMultiplier;
// update color the color
// calculate the percentage value of current force magnitude out of maximum
magPercent = (dragDistance * maxMultiplier) / (maxDragLength * maxMultiplier);
// choose color based on how close magPercent is to either 0 or max
currentColor = noForceColor * (1-magPercent) + maxForceColor * magPercent;
// dragzone color
dragZone.renderer.material.color = currentColor * new Color(1,1,1,0.2f);
// draw the line
Debug.DrawRay(transform.position, forceVector / maxMultiplier, currentColor);
}
//update the position of the dragzone
dragZone.transform.position = transform.position;
}
void OnMouseUp (){
mouseDragging = false;
if (overrideVelocity) {
// cancel existing velocity
rigidbody.AddForce(-rigidbody.velocity, ForceMode.VelocityChange);
}
// add new force
int snapD = 1;
if (snapDirection == SnapDir.away) snapD = -1; // if snapdirection is "away" set the force to apply in the opposite direction
rigidbody.AddForce(snapD * forceVector, forceTypeToApply);
// cleanup
dragZone.renderer.enabled = false;
if (pauseOnDrag) {
// un-pause the simulation
Time.timeScale = 1;
}
}
void OnGUI (){
if (mouseDragging) {
Vector2 guiMouseCoord = GUIUtility.ScreenToGUIPoint(Input.mousePosition);
GUI.Box ( new Rect(guiMouseCoord.x-30, Screen.height-guiMouseCoord.y+15, 100, 20), "force: "+Mathf.Round((forceVector).magnitude));
}
}
Mesh MakeDiscMeshBrute ( float r ){
Mesh discMesh;
Vector3[] dmVerts = new Vector3[18];
Vector3[] dmNorms = new Vector3[18];
Vector2[] dmUVs = new Vector2[18];
int[] dmTris = new int[48];
int i = 0;
discMesh = new Mesh();
dmVerts[0] = new Vector3(0,0,0);
dmVerts[1] = new Vector3(0,0,r);
dmVerts[2] = new Vector3(1,0,1).normalized * r; // find the vector at the correct distance the hacky-hillbilly way!
dmVerts[3] = new Vector3(r,0,0);
dmVerts[4] = new Vector3(1,0,-1).normalized * r;
dmVerts[5] = new Vector3(0,0,-r);
dmVerts[6] = new Vector3(-1,0,-1).normalized * r;
dmVerts[7] = new Vector3(-r,0,0);
dmVerts[8] = new Vector3(-1,0,1).normalized * r;
// set the other side to the same points
for (i = 0; i<dmVerts.Length/2; i++) {
dmVerts[dmVerts.Length/2 + i] = dmVerts[i];
}
for (i = 0; i<dmNorms.Length; i++) {
if (i<dmNorms.Length/2) dmNorms[i] = Vector3.up; // set side one to face up
else dmNorms[i] = -Vector3.up; // set side two to face down
}
dmUVs[0] = new Vector2(0,0);
dmUVs[1] = new Vector2(0,r);
dmUVs[2] = new Vector2(1,1).normalized * r;;
dmUVs[3] = new Vector2(r,0);
dmUVs[4] = new Vector2(1,-1).normalized * r;;
dmUVs[5] = new Vector2(0,-r);
dmUVs[6] = new Vector2(-1,-1).normalized * r;;
dmUVs[7] = new Vector2(-r,0);
dmUVs[8] = new Vector2(-1,1).normalized * r;;
// set the other side to the same points
for (i = 0; i<dmUVs.Length/2; i++) {
dmUVs[dmUVs.Length/2 + i] = dmUVs[i];
}
dmTris[0] = 0;
dmTris[1] = 1;
dmTris[2] = 2;
dmTris[3] = 0;
dmTris[4] = 2;
dmTris[5] = 3;
dmTris[6] = 0;
dmTris[7] = 3;
dmTris[8] = 4;
dmTris[9] = 0;
dmTris[10] = 4;
dmTris[11] = 5;
dmTris[12] = 0;
dmTris[13] = 5;
dmTris[14] = 6;
dmTris[15] = 0;
dmTris[16] = 6;
dmTris[17] = 7;
dmTris[18] = 0;
dmTris[19] = 7;
dmTris[20] = 8;
dmTris[21] = 0;
dmTris[22] = 8;
dmTris[23] = 1;
// side two
dmTris[24] = 9;
dmTris[25] = 11;
dmTris[26] = 10;
dmTris[27] = 9;
dmTris[28] = 12;
dmTris[29] = 11;
dmTris[30] = 9;
dmTris[31] = 13;
dmTris[32] = 12;
dmTris[33] = 9;
dmTris[34] = 14;
dmTris[35] = 13;
dmTris[36] = 9;
dmTris[37] = 15;
dmTris[38] = 14;
dmTris[39] = 9;
dmTris[40] = 16;
dmTris[41] = 15;
dmTris[42] = 9;
dmTris[43] = 17;
dmTris[44] = 16;
dmTris[45] = 9;
dmTris[46] = 10;
dmTris[47] = 17;
discMesh.vertices = dmVerts;
discMesh.uv = dmUVs;
discMesh.normals = dmNorms;
discMesh.triangles = dmTris;
return discMesh;
}
}
If you want to keep using the 3D Rigidbody, I'd suggest just using RigidbodyConstraints, so you can lock the z (or whatever) axis/rotation, and it will perform exactly the same as a 2D platformer.
I am following a tutorial in a book called Learn the Kinect API by Rob Miles.
Basically, it's an augmented reality game where spiders fall from the top of the screen and you hit them with a Mallet. After following the tutorial and looking at the codes, I understand how the spiders fall and how their position are randomized etc.
I have problem understanding the mallet though, I wish to replace the mallet with an image of a basket instead.
This is how the code for the mallet looks like
Brush malletHandleBrush = new SolidColorBrush(Colors.Black);
Brush malletHeadBrush = new SolidColorBrush(Colors.Red);
float malletHandleLength = 100;
float malletHeadLength = 50;
System.Windows.Vector malletPosition;
float malletHitRadius = 40;
bool malletValid = false;
void updateMallet(Joint j1, Joint j2)
{
// If Joint 1 (Right Wrist) or Joint 2 (Right Hand) is not tracked, we stop here
if (j1.TrackingState != JointTrackingState.Tracked || j2.TrackingState != JointTrackingState.Tracked)
return;
// Get the start and end positions of the mallet vector
ColorImagePoint j1P = myKinect.CoordinateMapper.MapSkeletonPointToColorPoint(j1.Position, ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint j2P = myKinect.CoordinateMapper.MapSkeletonPointToColorPoint(j2.Position, ColorImageFormat.RgbResolution640x480Fps30);
int dX = j2P.X - j1P.X;
int dY = j2P.Y - j1P.Y;
System.Windows.Vector malletDirection = new System.Windows.Vector(dX, dY);
if (malletDirection.Length < 1) return;
// Convert into a vector of length 1 unit
malletDirection.Normalize();
// now set the length of the mallet
System.Windows.Vector handleVector = malletDirection * malletHandleLength;
Line handleLine = new Line();
handleLine.Stroke = malletHandleBrush;
handleLine.StrokeThickness = 10;
handleLine.X1 = j1P.X;
handleLine.Y1 = j1P.Y;
handleLine.X2 = j1P.X + handleVector.X;
handleLine.Y2 = j1P.Y + handleVector.Y;
//malletCanvas.Children.Add(handleLine);
Line headLine = new Line();
headLine.Stroke = malletHeadBrush;
headLine.StrokeThickness = 50;
System.Windows.Vector headVector = malletDirection * malletHeadLength;
headLine.X1 = handleLine.X2;
headLine.Y1 = handleLine.Y2;
headLine.X2 = handleLine.X2 + headVector.X;
headLine.Y2 = handleLine.Y2 + headVector.Y;
//malletCanvas.Children.Add(headLine);
malletPosition = new System.Windows.Vector(j1P.X, j1P.Y);
malletPosition = malletPosition + (malletDirection * (malletHandleLength + (malletHeadLength / 2)));
malletValid = true;
}
This is how the code for detecting if the mallet hits the objects looks like
// Declare Hit Vector for each Dollar Note
System.Windows.Vector _spiderHitVector = new System.Windows.Vector(malletPosition.X - _spiderCenterX, malletPosition.Y - _spiderCenterY);
Does anyone have any resources or give me some hints on how to work on this?