- Home /
How would you set a camera lerp position with code not a child object?
I've run into this problem multiple times, being unable to set positions and rotations of a "child" object relative to moving and rotating "parents" with simply code instead of having to use a child object. I want to know how to do this without using child objects to artificiality solve this for me.
So lets say I'm trying to create a new promo video clip which has a camera following a pet while it kills enemies kind of a "Kill Cam".
I just tried to set this up and I'm always trying to improve my programming so naturally I start by trying to set the camera's rest position with code. But it seems every time I'm forced to just set up a child object attached to the parent to get the proper positions and rotations to work for me.
Can someone do a code example of how you could have similar results to always have the behaviors of a child object without it actually being a "child" object? I want the correct position and rotation relative to the parent for every frame without needing to use a child object.
Every single time I've tried this I end up having to use a stupid child object and it's really pissing me off I can't do it with just math or what seems like incredibly simple programming.
I feel like I'm missing a very simple and essential aspect of programming if I can't do this. I feel like using a child object through Unity is like a cheap short cut to true understanding of what I'm doing, I'd prefer to know how to do this without relying on a child object which is automatic.
Code Example:
//this script is on the camera
void LateUpdate()
{
//temporary messy solution for promo video
if (petObject == null)
{
petObject = GameObject.Find("Pet Baby Blue Beast");
petCameraTransform = GameObject.Find("Pet Camera Object").transform;
petCameraVector = petCameraTransform.position + new Vector3 (0, 2, 0);
}
//startTransform is just the camera's Transform
endDirectionVector = (petObject.transform.position + new Vector3 (0, 2, 0) - startTransform.position).normalized;
endRotationQuaternion = Quaternion.LookRotation(endDirectionVector);
startTransform.rotation = Quaternion.Slerp (startTransform.rotation, endRotationQuaternion, .5f);
startTransform.position = Vector3.Lerp (startTransform.position, petCameraTransform.position, .01f);
}
So the problem here is that I'm relying on the "Pet Camera Object" which gives me my petCameraTransform and resulting petCameraVector variables.
How can I do this without using a child object for the "Pet Camera Object"?
I feel like I've just somehow tried every single wrong possible combination of code to solve this without a child object. It seems the vector positions always get screwed up relative to the parent object whenever I try to simulate the child.
Maybe I'm over-thinking things and should just use the child object, but it really bothers me that I HAVE to use the child object.
I've had similar problems with other applications like visual blood effects where I feel I shouldn't need a child object to do it.
Answer by Scribe · Feb 16, 2014 at 04:25 PM
This doesn't include any smoothing but it does find the position the camera should be at and rotates the camera to face your object + some offset.
var target : Transform;
var followOffset : Vector3 = Vector3(0, 2, -5);
var lookOffset : Vector3 = Vector3(0, 1, 0);
private var localFollow : Vector3;
private var localLook : Vector3;
function Update () {
localFollow = target.position + target.TransformDirection(followOffset);
localLook = target.position+target.TransformDirection(lookOffset);
transform.position = localFollow;
transform.LookAt(localLook);
}
I haven't taken a look in quite a while but I seem to remember that the standard asset 3rd person camera controller does something similar to this (though a lot more advanced) but that might be a good place to look if this doesn't help.
Scribe
That looks promising!
Wow looks like there is a specific Unity Function TransformDirection built right in to do exactly what I was trying to do with all my failures ^^
Thanks for answer, I can't believe I never knew about that, can't even remember seeing it in any of the 100's of posts I've read here.
I'll have to give it a try next time I set something like this up, Gonna accept your answer even though I didn't test it yet.
I'd still be curious how to do it with just the raw math involved ins$$anonymous$$d of a Unity Function but I guess that's just not worth it even these days.
The raw maths of the position of the object is quite easy, the following code should achieve the effect:
var target : Transform;
var followOffset : Vector3 = Vector3(0, 2, -5);
private var localFollow : Vector3;
function FollowPosition(obj : Transform, offset : Vector3) : Vector3{
var returnVector : Vector3 = obj.position+(obj.right*offset.x)+(obj.up*offset.y)+(obj.forward*offset.z);
return returnVector;
}
function Update () {
localFollow = FollowPosition(target, followOffset);
transform.position = localFollow;
}
The rotation part is quite a bit harder if you want to do it completely from scratch but still do-able and can be done with some classical mechanics. If you don't $$anonymous$$d using some other built-in stuff you can do it by using the same FollowPosition method from above:
function Update(){
transform.forward = FollowPosition(target, lookOffset)-transform.position;
}
If you aren't happy with setting the forward of the transform (as it is basically the same as using LookAt) you will have to use some mechanics as I mentioned above. I have not checked this so I may be wrong but I think this is what you would need to do:
First find the direction from your following object to the point it should look at (the same as I did just above)
Then get the axis that is orthoganal (90degrees to) the direction you just found and the object that you are followings forward direction. To do this you can use the cross product of 2 vectors, Unity has this built in (see Vector3.Cross)
Find the angle that you need to rotate around this axis by finding the dot product, dividing by the magnitude of the vectors mutiplied and taking the arccosine. Something along the lines of
$$anonymous$$athf.Acos(Vector3.Dot(direction.normalized, obj.forward))*$$anonymous$$athf.Rad2Deg
(See Vector3.Dot)Then you can get a rotation from this angle axis notation using Quaternion.AngleAxis
If your still not satisfied using the builting ANgleAxis operation then check out this link, there is also some code slightly further down the page which you can convert to Unityscript/C#
If you have trouble following any of that let me know, I may try to do this myself from raw maths as it seems like a good exercise for my mechanics!
Have fun,
Scribe