- Home /
Camera Follow Player using a path
Hi, it is been a while that I don't come here, so I need you help with a question about a code that I trying to implement for the past 2 weeks. I saw a lot of tutorials and tryed a lot of things but I am not a code expert. I have this first code that I learned in this tutorial.
https://www.youtube.com/watch?v=B3LYJINnYtE&t=651s
public Transform[] nodes;
private int nodeCount;
public int nearstnode;
// Use this for initialization
private void Start () {
nodeCount = transform.childCount;
nodes = new Transform[nodeCount];
for (int i = 0; i < nodeCount - 1; i++) {
nodes [i] = transform.GetChild (i);
}
}
// Update is called once per frame
private void Update () {
if (nodeCount > 1) {
for (int i = 0; i < nodeCount - 1; i++) {
Debug.DrawLine (nodes[i].position, nodes[i+1].position, Color.green);
}
}
}
public Vector3 ProjectPositionOnRail(Vector3 pos){
int ClosestNodeIndex = GetClosestNode(pos);
if (ClosestNodeIndex == 0) {
return ProjectOnSegment (nodes [0].position, nodes [1].position, pos);
} else if (ClosestNodeIndex == nodeCount - 1) {
return ProjectOnSegment (nodes [nodeCount-1].position, nodes [nodeCount-2].position, pos);
} else {
Vector3 LeftSeg = ProjectOnSegment (nodes [ClosestNodeIndex - 1].position , nodes [ClosestNodeIndex].position, pos);
Vector3 RightSeg = ProjectOnSegment (nodes [ClosestNodeIndex + 1].position, nodes [ClosestNodeIndex].position, pos);
Debug.DrawLine (pos, LeftSeg, Color.red);
Debug.DrawLine (pos, RightSeg, Color.blue);
if ((pos - LeftSeg).sqrMagnitude <= (pos - RightSeg).sqrMagnitude) {
return LeftSeg;
} else {
return RightSeg;
}
}
}
private int GetClosestNode(Vector3 pos){
int ClosestNodeIndex = -1;
float ShortestDistance = 0.0f;
for (int i = 0; i < nodeCount; i++) {
float sqrDistance = (nodes [i].position - pos).sqrMagnitude;
if (ShortestDistance == 0.0f || sqrDistance < ShortestDistance) {
ShortestDistance = sqrDistance;
ClosestNodeIndex = i;
}
}
nearstnode = ClosestNodeIndex;
return ClosestNodeIndex;
}
public Vector3 ProjectOnSegment(Vector3 v1, Vector3 v2, Vector3 pos){
Vector3 v1ToPos = pos - v1;
Vector3 segDirection = (v2 - v1).normalized;
float DistanceFromV1 = Vector3.Dot (segDirection, v1ToPos);
if (DistanceFromV1 < 0.0f) {
return v1;
} else if (DistanceFromV1 * DistanceFromV1 > (v2 - v1).sqrMagnitude) {
return v2;
} else {
Vector3 fromV1 = segDirection * DistanceFromV1;
return v1 + fromV1;
}
}
and the code to control the camera along this rail:
public SCRIPTS_CameraRail Rail;
public Transform Player;
public float MoveSpeed = 5.0f;
public Transform thisTransform;
public Vector3 LastPosition;
// Use this for initialization
private void Start () {
thisTransform = transform;
LastPosition = thisTransform.position;
}
// Update is called once per frame
private void Update () {
LastPosition = Vector3.Lerp (LastPosition, Rail.ProjectPositionOnRail (Player.position), Time.deltaTime * MoveSpeed);
thisTransform.position = LastPosition;
}
this is a pretty god system but I was trying to make this rail becomes smoother with curves, so I saw this tutorial: https://www.youtube.com/watch?v=Xwj8_z9OrFw&t=548s and tryed to implement the curve calculation in the rail system, the math works pretty fine, but I never figured out how to implement the calculation in the rail system code.
some weeks later I found this tutorial: https://www.youtube.com/watch?v=URqjHIz6pts&t=1594s
and implemented the code:
public Transform[] nodes;
private int nodeCount;
// Use this for initialization
void Start () {
nodeCount = transform.childCount;
nodes = new Transform[nodeCount];
for (int i = 0; i < nodeCount; i++) {
nodes [i] = transform.GetChild (i);
}
}
// Update is called once per frame
void Update () {
}
public Vector3 LinearPosition(int seg, float ratio){
Vector3 p1 = nodes [seg].position;
Vector3 p2 = nodes [seg + 1].position;
return Vector3.Lerp (p1, p2, ratio);
}
public Vector3 CatmullPosition(int seg, float ratio){
Vector3 p1, p2, p3, p4;
if (seg == 0) {
p1 = nodes [seg].position;
p2 = p1;
p3 = nodes [seg + 1].position;
p4 = nodes [seg + 2].position;
} else if (seg == nodes.Length - 2) {
p1 = nodes [seg - 1].position;
p2 = nodes [seg].position;
p3 = nodes [seg + 1].position;
p4 = p3;
} else {
p1 = nodes [seg - 1].position;
p2 = nodes [seg].position;
p3 = nodes [seg + 1].position;
p4 = nodes [seg + 2].position;
}
float t2 = ratio * ratio;
float t3 = t2 * ratio;
float x = 0.5f * ((2.0f * p2.x)
+ (-p1.x + p3.x)
* ratio + (2.0f * p1.x - 5.0f * p2.x + 4 * p3.x - p4.x)
* t2 + (-p1.x + 3.0f * p2.x - 3.0f * p3.x + p4.x)
* t3);
float y = 0.5f * ((2.0f * p2.y)
+ (-p1.y + p3.y)
* ratio + (2.0f * p1.y - 5.0f * p2.y + 4 * p3.y - p4.y)
* t2 + (-p1.y + 3.0f * p2.y - 3.0f * p3.y + p4.y)
* t3);
float z = 0.5f * ((2.0f * p2.z)
+ (-p1.z + p3.z)
* ratio + (2.0f * p1.z - 5.0f * p2.z + 4 * p3.z - p4.z)
* t2 + (-p1.z + 3.0f * p2.z - 3.0f * p3.z + p4.z)
* t3);
return new Vector3 (x, y, z);
}
public Quaternion Orientation(int seg, float ratio){
Quaternion q1 = nodes [seg].rotation;
Quaternion q2 = nodes [seg + 1].rotation;
return Quaternion.Lerp (q1, q2, ratio);
}
and the camera controller:
public SCRIPTS_CameraRail2 Rail;
public Transform PlayerTransform;
public int currentSeg;
private float transition;
private bool isCompleted;
public float PlayerToNode1Distance, PlayerToNode2Distance, NodeDistance, d;
public Vector3 Line, LineStart, LineEnd, Point, Dir;
// Update is called once per frame
void Update () {
if (!Rail) {
return;
}
if (!isCompleted) {
Play ();
}
}
private void Play(){
transition += Time.deltaTime * 1 /2.5f;
if (transition > 1) {
transition = 0;
currentSeg++;
}else if(transition < 0){
transition = 1;
currentSeg--;
}
transform.position = Rail.CatmullPosition (currentSeg, transition);
transform.rotation = Rail.Orientation (currentSeg, transition);
}
In this second code I know that I need to change the transition value to move the camera, but dont know how to make this happen based on the player position.
So I have one code that moves based on the players position but have no curves, and a second code that move with curves but dont move based on the players position. how can I make this 2 things in only one code? move based on players position true the rail with curves to make the camera movement smoother.
thanks for any help!