- Home /
Make one GameObject look at, move toward another across a sphere
I have two game objects on a sphere. Using code derived form: http://wiki.unity3d.com/index.php/WalkOnSphere one object is moving on the sphere. I want the second object to orient toward the first and walk towards it.
I tried to get the Quaternion.Angle of the two object's Quaternions and then set that angle on the follower, that makes the follower walk toward the first object and then start circling it, which is actually something I'd like to be able to control with set radiuses, but was not intentional. Also the follower starts spinning on the spot if the target s moving too quickly across the sphere.
using UnityEngine;
using System.Collections;
// SEE: http://answers.unity3d.com/questions/41050/how-can-i-make-movement-on-a-sphere.html
public class CharacterBehavior : MonoBehaviour, ISphericalMoveable {
private GameObject planet;
public Vector3 direction = Vector3.one;
public float radius = 6f;
public float angle = 0f;
public Quaternion rotation = Quaternion.identity;
public Animator animator;
public bool walkAround = false;
public ISphericalMoveable targetChar;
void Awake() {
this.animator = this.transform.GetComponent<Animator>();
}
// Use this for initialization
void Start () {
this.planet = GameObject.Find("Planet");
this.radius = this.planet.transform.localScale.y;
}
public virtual void OnAnimatorMove()
{
if( this.walkAround){
// THE PROBLEM
// Find the angle required to walk around the target
// Part one of the problem
// - make the charater walk toward the character - angle toward it
// Part two
// - as you get closer to the target alter the angle
// - so that when it gets really close the angle is always perpendicular to the direction it needs to travel in.
// TODO: make this.angle a property of the animator - so that it can affect the animation.
/**
* THIS WORKSISH - see description of problems in question above
float targetAngle = Quaternion.Angle( rotation, this.targetChar.GetRotation());
this.angle = targetAngle;
**/
}
if (this.animator)
{
this.direction = new Vector3(Mathf.Sin(this.angle), Mathf.Cos(this.angle));
Translate(0, this.animator.GetFloat("Speed"));
UpdatePositionRotation();
}
}
void Translate(float x, float y)
{
Vector3 perpendicular = new Vector3(-direction.y, direction.x);
Quaternion verticalRotation = Quaternion.AngleAxis(y * Time.deltaTime, perpendicular);
Quaternion horizontalRotation = Quaternion.AngleAxis(x * Time.deltaTime, direction);
rotation *= horizontalRotation * verticalRotation;
}
void UpdatePositionRotation()
{
transform.localPosition = rotation * Vector3.forward * radius;
transform.rotation = rotation * Quaternion.LookRotation(direction, Vector3.forward);
}
public Quaternion GetRotation()
{
return this.rotation;
}
public Transform GetTransform()
{
return this.transform;
}
public void StartWalking()
{
this.animator.SetFloat("Speed", 4f);
}
public void StartWalkingAround(ISphericalMoveable character){
this.walkAround = true;
this.targetChar = character;
}
public void StopWalkingAround(){
this.walkAround = false;
}
}
using UnityEngine;
using System.Collections;
public interface ISphericalMoveable
{
Quaternion GetRotation();
Transform GetTransform();
}
Here's an answer to a similar question, which rotates a game object toward another game object on a sphere. Don't know if it's of any use for you now but perhaps some lonesome soul search the site and finds it.
Answer by mah_0003 · Mar 02, 2015 at 01:39 PM
Well, you could use walktowards.Transform.LookAt(); and as to walking towards said object, you could get the character to point at the object and then use vector3 changes. I'm not very good myself at automated walking or pathfinding, but a think using LookAt would make a lot of the code shorter. For help, try this: http://docs.unity3d.com/ScriptReference/Transform.LookAt.html
Just a small fix, Good luck.