0
\$\begingroup\$

I'm working on a 3D game in Unity that requires lock-on, or Z, targeting found in games like Dark Souls and Legend of Zelda: Ocarina of Time.

The code that I have achieves my intended goals fairly closely, but as the title states, the player moves around the target in a spiral pattern, rather than a perfect circle: After each revolution around the target, the player gets further and further away instead of remaining at the same distance.

I tried many different proposed solutions and looked all over, but nothing fixed this issue; please advise:

using System; using UnityEngine; public class Movement : MonoBehaviour { internal Rigidbody rb; private float x, y, z; //Float Scalar for the Vector Movement Speed public float vel; private float angleVel; private float hAxis, vAxis; internal Vector3 moveVec; //Boolean to control whether or not Movement is possible, based on other states. public bool bCanWalk; //Enemy to which the player is locked-on. public GameObject target; internal Vector3 targetterToTarget; private Vector3 crossProd; void Start() { rb = GetComponent<Rigidbody>(); rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ; } void Update() { //Move once per frame Move(); } void Move() { y = rb.velocity.y; hAxis = Input.GetAxisRaw("Horizontal"); vAxis = Input.GetAxisRaw("Vertical"); targetterToTarget = transform.position - target.transform.position; crossProd = MathHelper.CrossProd(target.transform.up.normalized, targetterToTarget.normalized); switch (hAxis) { case -1: case 1: x = crossProd.x * -hAxis * vel; z = crossProd.z * -hAxis * vel; break; default: angleVel = 0; x = 0; z = vAxis * vel; break; } SetMoveVec(); rb.velocity = moveVec; } private void SetMoveVec() { moveVec.x = x; moveVec.y = y; moveVec.z = z; } } 
using System; using UnityEngine; public static class MathHelper { public static Vector3 CrossProd(Vector3 targetForwardNormalized, Vector3 targetterToTargetNormalized) { Vector3 crossProdVar; crossProdVar.x = (targetForwardNormalized.y * targetterToTargetNormalized.z) - (targetForwardNormalized.z * targetterToTargetNormalized.y); crossProdVar.y = (targetForwardNormalized.z * targetterToTargetNormalized.x) - (targetForwardNormalized.x * targetterToTargetNormalized.z); crossProdVar.z = (targetForwardNormalized.x * targetterToTargetNormalized.y) - (targetForwardNormalized.y * targetterToTargetNormalized.x); return crossProdVar; } } 

Thank you.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You are including any Y axis variation from targetterToTarget.normalized in the cross product; spinning around a tilting axis resulting in a spiral motion.

Zero the Y differences to allow a circular orbit on the XZ axis:

targetterToTarget.X = transform.position.X - target.transform.position.X; targetterToTarget.Z = transform.position.Z - target.transform.position.Z; targetterToTarget.Y = 0; ``` 
\$\endgroup\$
3
  • \$\begingroup\$ Thank you for the quick reply. I tried several variations of your suggestion, but unfortunately, none of them worked - the spiraling persisted. Here they are: targetterToTarget = transform.position - target.transform.position; targetterToTarget.y = 0; I also swapped the Vectors below in 1 other attempt: targetterToTarget.x = transform.position.x - target.transform.position.x; targetterToTarget.z = transform.position.z - target.transform.position.z; targetterToTarget.y = 0; Any other ideas? \$\endgroup\$ Commented Jan 11 at 0:34
  • \$\begingroup\$ @FireStriker , sorry, Shouldn't target.transform.up be target.transform.forward.normalized? \$\endgroup\$ Commented Jan 11 at 0:47
  • \$\begingroup\$ I don't think so; every resource I've come across states that finding the cross product (Which is necessary to determine whether or not an entity is to the left or right of another) uses the targeter-to-target and target up vectors as input. Nevertheless, I tried your suggestion, but the result is that now, the player doesn't move around the target at all: targetterToTarget = transform.position - target.transform.position; targetterToTarget.y = 0; crossProd = MathHelper.CrossProd(target.transform.forward.normalized, targetterToTarget.normalized); Any other ideas you can suggest? \$\endgroup\$ Commented Jan 15 at 6:39

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.