I’m working on a Planet like prove of concept. I’m using Rune’s locomotion system PhysicsCharacterMotor to move my player and the NPCs around the planet. The player has also the PlatformCharacterController to capture the input and move the player, but for my NPCs that need to follow my player, I’m adapting the Platform Character Controller with the Follower script. So far, I’m able to make the NPCs follow pretty well along the horizontal axis of my planet, but when moving along the vertical axis, my NPCs don’t follow.
I’m a rookie in terms of the unity mathematics and physics, so any help would be awesome.
Here’s my current script. I’m calling the Follow() and Stop() methods from another script when the player is in range.
using UnityEngine;
using System.Collections;
public class FollowController : MonoBehaviour
{
private CharacterMotor motor;
// Follow settings
public float desiredDistance;
public float walkMultiplier = 0.5f;
// Use this for initialization
void Start () {
motor = GetComponent(typeof(CharacterMotor)) as CharacterMotor;
if (motor==null)
Debug.Log("Follow Controller: Motor is null!!");
}
// Moves the character according to the received target.
public void Follow (Transform target)
{
// get direction to target
Vector3 targetVector = target.position-transform.position;
targetVector = Util.ProjectOntoPlane(targetVector, transform.up).normalized * targetVector.magnitude;
float speed = (targetVector.magnitude-desiredDistance)*2;
print("Target Vector Distance: " + targetVector.magnitude);
Vector3 directionVector = targetVector.normalized * speed;
//if (targetVector.magnitude > 1)
// targetVector = targetVector.normalized;
//Vector3 directionVector = targetVector.normalized * Mathf.Pow (targetVector.magnitude, 2);
// Rotate input vector into camera space so up is camera's up and right is camera's right
directionVector = Camera.main.transform.rotation * directionVector;
// Rotate input vector to be perpendicular to character's up vector
Quaternion camToCharacterSpace = Quaternion.FromToRotation (Camera.main.transform.forward * -1, transform.up);
directionVector = (camToCharacterSpace * directionVector);
// Make input vector relative to Character's own orientation
directionVector = Quaternion.Inverse (transform.rotation) * directionVector;
directionVector *= walkMultiplier;
// Apply direction
motor.desiredMovementDirection = directionVector;
motor.desiredFacingDirection = targetVector.normalized;
}
public void Stop ()
{
motor.desiredMovementDirection = Vector3.zero;
}
}
I went back to the original Rune’s follower script, but I need to make it work in a planet like surface.
Any help will be really appreciated.
using UnityEngine;
using System.Collections;
public class FollowController : MonoBehaviour
{
private CharacterMotor motor;
// Follow settings
public float desiredDistance;
public float walkMultiplier = 0.5f;
// Use this for initialization
void Start () {
motor = GetComponent(typeof(CharacterMotor)) as CharacterMotor;
if (motor==null)
Debug.Log("Follow Controller: Motor is null!!");
}
// Moves the character according to the received target.
public void Follow (Transform target)
{
// get direction to target
Vector3 targetVector = target.transform.position-transform.position;
targetVector = Util.ProjectOntoPlane(targetVector, transform.up).normalized * targetVector.magnitude;
float speed = (targetVector.magnitude-desiredDistance)*2;
Vector3 directionVector = targetVector.normalized * speed;
// Apply direction
CharacterMotor motor = GetComponent(typeof(CharacterMotor)) as CharacterMotor;
motor.desiredMovementDirection = directionVector;
motor.desiredFacingDirection = targetVector;
}
public void Stop ()
{
motor.desiredMovementDirection = Vector3.zero;
}
}
I just made it work. I needed to make the direction vector relative to the NPC’s own orientation and I removed the Util.ProjectOntoPlane() function and it is working pretty well. If you are creating a planet like game, and you are using Rune’s locomotion system, this will make your NPC’s follow your character around the planet.
Just to clear things out, you don’t need to use locomotion (I’m not using locomotion for my NPC’s, just for the player). For the NPC’s I’m using Rune’s PhysicsCharacterMotor.cs (which uses the CharacterMotor.cs). The NPC’s also have a CapsuleCollider, a RigidBody, the FollowerController I created based on Rune’s Follower script and one extra script to call the Follow() and the Stop() methods of the FollowerController script.
Hope is helpful for other people.
using UnityEngine;
using System.Collections;
public class FollowController : MonoBehaviour
{
private CharacterMotor motor;
// Follow settings
public float desiredDistance;
public float walkMultiplier = 0.5f;
// Use this for initialization
void Start () {
motor = GetComponent(typeof(CharacterMotor)) as CharacterMotor;
if (motor==null)
Debug.Log("Follow Controller: Motor is null!!");
}
// Moves the character according to the received target.
public void Follow (Transform target)
{
// get direction to target
Vector3 targetVector = target.position-transform.position;
float speed = (targetVector.magnitude-desiredDistance)*2;
Vector3 directionVector = targetVector.normalized * speed;
// Make direction vector relative to character's own orientation
directionVector = Quaternion.Inverse (transform.rotation) * directionVector;
motor.desiredMovementDirection = directionVector;
motor.desiredFacingDirection = targetVector;
}
public void Stop ()
{
motor.desiredMovementDirection = Vector3.zero;
}
}
Just curious why you chose a physics based controller for you NPCs. I’m moving several spider-like creatures and am playing with both physics and standard programmatic character controllers. I’m not finding a clear answer on the forums as to the advantages of one over the other in terms of CPU usage etc. Obviously, physics allows for some more realistic interactions, but how about the cost? Just wondering if you have some insights you can share. Thanks.
The point is, that there are no clear cut advantages. It has to do with how you want to make your system. I created a pure physics character controller. I put some boxes on a plane and went under them and jumped, the boxes flew up. I was happy. I did the same thing with a Character Controller controlled character and they did not move.
It really has to do with what you are doing, and how you want to accomplish it. There are no massive advantages either way, nor disadvantages (save what I mentioned)
Processing wise, No rigid bodies = no physics overhead. That is an advantage. But no physics = no interactivity. That is a disadvantage.
Decide which way you want to go, and go that way. It really is that simple.
Hi I would like to know how I could get my A.I to get into a vehcile and control it on a planetary surface I have this very basic A.I which should come after the player though it doesn’t shoot any weapons or anything
using System.Collections;
public class EnemyAI: MonoBehaviour {
Vector3 Enemy_AImoveAmount;
Rigidbody Enemy_AIRigidbody;
Transform tr_Player;
public LayerMask groundedMask;
float f_RotSpeed=60.0f,f_MoveSpeed = 40.0f;
public float walkSpeed = 40;
// Use this for initialization
void Start () {
tr_Player = GameObject.FindGameObjectWithTag ("Player").transform; }
// Update is called once per frame
void Update () {
/* Look at Player*/
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (tr_Player.position - transform.position), f_RotSpeed * Time.deltaTime);
/* Move at Player*/
transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
}
void FixedUpdate() {
// Apply movement to rigidbody
Vector3 localMove = transform.TransformDirection(Enemy_AImoveAmount) * Time.fixedDeltaTime;
GetComponent<Rigidbody>();Enemy_AIRigidbody.MovePosition(GetComponent<Rigidbody>().position + localMove);
}
}