- Home /
How do i Update a Transforms Position, and how do i have objects face along a spline??
Hello i am having two issues, that i need help with.
(1). How do i update a Transfrom position when i move it like this in Pic1(Each time i try to do this it'll either spawn a whole bunch of objects then crash or not work)??
-Pic1
(2). And also i have been trying to do this for a long time how do i face objects in the z axis along a spline like this in Pic2??
-Pic2
Here is my code so you know what i have done.
using UnityEngine;
using System.Collections.Generic;
public class Spline : MonoBehaviour {
public List<Transform> controlPointsList = new List<Transform>();
public int segCount = 2;
public Transform segment;
Vector3 position;
void Start()
{
duplicateObject(segment, segCount);
}
public void duplicateObject(Transform original, int seg)
{
seg++;
for (int i = 0; i < controlPointsList.Count - 1; i++)
{
for (int j = 1; j < seg; j++)
{
position = controlPointsList[i].position + j * (controlPointsList[i + 1].position - controlPointsList[i].position) / seg;
var a = Instantiate(original, position, Quaternion.identity) as Transform;
Vector3 rotation = controlPointsList[i].position + j * (controlPointsList[i + 1].position - controlPointsList[i].position);
a.rotation = Quaternion.LookRotation(rotation);
}
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.white;
for (int i = 0; i < controlPointsList.Count; i++)
{
Gizmos.DrawWireSphere(controlPointsList[i].position, 0.3f);
}
for (int i = 0; i < controlPointsList.Count-1; i++)
{
Gizmos.DrawLine(controlPointsList[i].position, controlPointsList[i + 1].position);
}
}
}
Answer by b1gry4n · Sep 03, 2016 at 02:16 AM
I went through and made a script that will do what you want, but since I dont know how you are creating your spline (i am guessing you are using transforms judging by the gizmos, so it isnt really a spline at the moment) I am just using regular Transforms for control points. When you get to making the spline, youre going to have to change how you are positioning these objects along it. The script below works as a solution to the question you asked with the given information. This tutorial gives insight into how placing objects along a spline is done: http://catlikecoding.com/unity/tutorials/curves-and-splines/
And after moving the control nodes around in runtime i get this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SplineTest : MonoBehaviour {
public class SplinePoint
{
public Transform t;
public Transform cpAhead;
public Transform cpBehind;
public int seg;
public SplinePoint(Transform thetrans, Transform a, Transform b, int s)
{
t = thetrans;
cpAhead = a;
cpBehind = b;
seg = s;
}
}
public List<Transform> controlPointsList;
public List<SplinePoint> splinePoints;
public GameObject segment;
public int segCount = 2;
public float updateRate = 0.25f;
public bool setup = false;
public bool running = false;
void Start()
{
splinePoints = new List<SplinePoint>();
CreateObjects(segment);
}
public void CreateObjects(GameObject original)
{
for (int i = 0; i < controlPointsList.Count - 1; i++)
{
for (int j = 0; j < segCount; j++)
{
GameObject a = (GameObject)Instantiate(original, Vector3.zero, Quaternion.identity);
splinePoints.Add(new SplinePoint(a.transform, controlPointsList[i + 1], controlPointsList[i], j));
}
}
setup = true;
}
void Update()
{
if (setup && !running)
{
running = true;
InvokeRepeating("UpdateSplinePos", 0, updateRate);
}
}
void UpdateSplinePos()
{
for (int i = 0; i < splinePoints.Count; i++)
{
SetPosition(splinePoints[i]);
}
}
void SetPosition(SplinePoint sp)
{
float dist = Vector3.Distance(sp.cpAhead.position, sp.cpBehind.position);
float step = dist / (segCount + 1);
Vector3 dir = (sp.cpAhead.position - sp.cpBehind.position).normalized;
sp.t.position = sp.cpBehind.position + ((dir * step) * (sp.seg + 1));
sp.t.rotation = Quaternion.LookRotation(dir);
}
}
Thanks @b1gry4n for the help Problem2 is now solved now for Problem1, i did try what you did with the update thing and i don't know how to do it correctly, i map the properties in another void(UpdateObjects) then put them in Update() but the duplicateObject cant read the position which i calculated in UpdateObjects(), would you know how to do this?
here is my sh*tty code :D
Vector3 position;
void Start()
{
duplicateObject(segment, segCount);
}
public void duplicateObject(Transform original, int seg)
{
seg++;
for (int i = 0; i < controlPointsList.Count - 1; i++)
{
for (int j = 1; j < seg; j++)
{
var a = Instantiate(original, position, Quaternion.identity) as Transform;
Vector3 dir = controlPointsList[i].position - controlPointsList[i+1].position;
a.rotation = Quaternion.LookRotation(dir);
}
}
}
void Update()
{
UpdateObjects();
}
void UpdateObjects()
{
for (int i = 0; i < controlPointsList.Count - 1; i++)
{
for (int j = 1; j < segCount; j++)
{
position = controlPointsList[i].position + j * (controlPointsList[i + 1].position - controlPointsList[i].position) / segCount;
}
}
}
Check the edited post, I gave an example of a working solution