Dear community, I come to add up to the pile of questions about handling moving platforms. Nevertheless, at least in my defense I feel that my question brings some new flavors and complexity that might be of interest to others.
My 3D game has some very big platforms that move both vertically and horizontally, as well as sometimes rotate a bit (somewhat similar to the Pirate Ship ride present in real life parks). I need NPCs to walk over these platforms when platforms are moving in these many ways, as well as the main player, of course. Maybe it is worth mentioning that mine is not a FPS game: movement more-or-less resembles that of RTS, since the main character follows mouse clicks (so, if it helps, I can use solutions that disable gravity of objects, since it is not crucial to my application).
Of course, I have found the very many questions about moving platforms. Some have shed light to my problem, but in general none was able to fully solve my issues. I set the platforms to be parent of the NPC objects, and these I set as Kinematic. When not in movement, the NPCs follow the platform suitably: up, down, to any side, even rotate together. However, when they move at the same time as these platforms, problems begin to arise. It is almost as if NPCs got detached, since their movement do not follow the platform and they end up out of it. When NPCs are moving and platform rotates, the scenario is even worse: NPCs’ meshes are crazily.
Here you have a small example of code I’ve been trying in order to test the mechanics:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
public GameObject person; //this represents either the NPC or the main player
public GameObject floor; //this represents the platform
private Vector3 target;
private bool walking = false;
private Vector3 temp;
private Renderer floor_rend;
private Vector3 floor_center;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButtonDown(0)){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit)){
Debug.DrawLine (ray.origin, hit.point);
}
target = new Vector3(hit.point.x, hit.point.y, hit.point.z);
//store the difference between point hit by ray and the centroid of the platform mesh
floor_center = floor.GetComponent<Renderer>().bounds.center;
temp= target - floor_center;
walking = true;
}
//making NPC move
if(c1+floor_center != person.transform.position && walking){
person.transform.LookAt(c1+floor_center);
person.transform.Translate(Vector3.forward * Time.deltaTime*2);
if(c1+floor_center == person.transform.position){walking = false;}
}
//Input keys to make the platform move
if(Input.GetKey("a")) floor.transform.Translate(Vector3.back*Time.deltaTime);
if(Input.GetKey("d")) floor.transform.Translate(Vector3.forward*Time.deltaTime);
if(Input.GetKey("w")) floor.transform.Translate(Vector3.up*Time.deltaTime);
if(Input.GetKey("s")) floor.transform.Translate(Vector3.down*Time.deltaTime);
if(Input.GetKey("e")) floor.transform.Rotate(Mathf.Lerp(0, 45, Time.deltaTime), 0, 0);
if(Input.GetKey("q")) floor.transform.Rotate(Mathf.Lerp(0, -45, Time.deltaTime), 0, 0);
}
}
Any ideas will be very much appreciated.