I am developing a game that uses a third person camera view, character centralized, no issues with that. But I can't find a way to "lock" on another object while keeping my character in view (Rocket League ball cam: https://youtu.be/FDcO04gXihM ).
I am aware of lookAt() method but it's not enough on its own. I still need to calculate the position of the camera to avoid staying between the player and the target. The problem: http://imgur.com/a/MdO9m
This is what I'm currently doing to move the camera (the "free cam"):
if (freeCam) {
transform.position = Vector3.Lerp(transform.position, camTarget.transform.position, speed);
transform.rotation = Quaternion.Lerp(transform.rotation, camTarget.transform.rotation, speed);
} else {
// Lock cam
}
The camTarget is a game object parented to the player.
I now understand what your problem is and try to explain the solution.
Let's say you have the player object as PO and the target object TO and the camera object CO.
So when you want to achieve, to follow with the camera view always the target object and keep the player object in between, all you have to do ->
The CO needs to travel around the PO in an orbit (orbital camera) with a fixed distance.
Next create a vector from the point TO to PO (the center of the orbit of CO)
Then calculate the 2 hit points of the vector (TO|PO) with the orbit. You now have an enter hit point ENP and an exit hit point EXP.
As of vectors have always a direction the EXP will always be the further point if you keep the direction from TO to PO.
Set the CO position to EXP and lookat at TO
Apply an fixed offset to EXP corresponding to the world.upvector to always sit above the PO.
[optional] If surface exists, do a collision detection with EXP against the surface. If hit, set EXP to collision detection point, and set PO render to false. As soon EXP is no longer colliding with surface set PO render to true.
[optional] If want to achieve to always have a good view rather then always a good look at PO, take the angle of the forward vector of CO. If it is quarter I of IV (position of a angle in math) you can assume, that ur currently just seeing the PO and not TO because the camera sits right beyond PO and looks to TO right through PO. If this happens set PO render to false. As soon as CO forward vector angle is quarter II-IV set PO render to true.
That's it. I will try to give u more in depth code tonight, because right now I'm at work.
Maybe you could check if the camera's position is between the player and the target and just rotate it 180ยบ
Related
I have a laser turret in Unity3D, which I'd like to turn towards the enemies. The turret consists of a "leg" and a "head" (selected on the picture 1). The head can pan and tilt around a spherical joint.
I do the following:
Vector3 targetDir = collision.gameObject.transform.position - turretHead.transform.position;
float step = turnSpeed * Time.deltaTime;
Vector3 newDir = Vector3.RotateTowards(turretHead.transform.forward, targetDir, step, 0.0f);
turretHead.transform.rotation = Quaternion.LookRotation(newDir);
The problem is that since the pivot of the head is not aligned with the laser beam, the turret turns into the almost right direction, but it shoots above the target. (It would hit perfectly, if the laser would come out of the red axis of the pivot.)
Is there a builtin method or some trick to achieve the correct functionality other then doing the calculation myself?
Okay, here's the quick and easy way to do this. It's probably "better" to do it with proper trig, but this should give you the result you want pretty quick:
If you don't already have a transform aligned with the barrel, then create an empty GameObject and line it up (make sure it's a child of the turret so they move together). Add a reference to your script for it's transform.
Then, in your first line, calculate from the new Barrel transform instead of the turretHead transform. Leave everything else the same. This way it calculates from the turret barrel, but moves the turret head.
Now, this approach isn't perfect. If the pivot center is too offset from the barrel transform, then it would be less accurate over large moves, or when aiming at something close by, because the expected position when aiming would be different than the initial position due to the rotation pivot being elsewhere. But this can be solved with iteration, as the calculation would become more accurate the closer it is to it's desired goal.
To give you the setting: I'm making a Vive game in zero-g, where the player moves by grabbing handles and propelling themselves.
What I'd like is for the player to be able to rotate themselves, by grabbing a handle with both hands. Imagine how you'd move in zero-g if you held on to a bar with both hands.
To illustrate:
On the left hand side the player has grabbed a handlebar with both hands. Left arm extended, right arm bent.
In the right hand side picture the player has now extended their right arm, which has rotated the player around the bar.
I guess it's easier to see it as if the player would be moving the entire world, when they do this.
My question is: How can I do this in Unity in 3 dimensions, either through math of Unity-trickery? It needs to roll, yaw and position the player relative to the hands.
Thank you!
Record the average of the three vectors. Then in the next frame, get the difference from the previous average. The difference can be used as euler angles to apply constant force to a rigidbody (or rotate an object by that amount, or other possibilities, depending on your goals).
https://docs.unity3d.com/ScriptReference/Transform.Rotate.html
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
Vector3 previousCenterPoint;
void Update() {
Vector3 newCenterPoint = (leftHand.transform.position + rightHand.transform.position + player.transform.position) / 3f;
if (previousCenterPoint != null)
{
Vector3 someEulerAngles = newCenterPoint - previousCenterPoint;
someRigidBody.AddForce(someEulerAngles, ForceMode.VelocityChange);
}
previousCenterPoint = newCenterPoint;
}
Hey guys how do I find the rotation of the phone with Google Cardboard SDK in Unity3D, like the way the persons head is facing? I need to find if it is facing more towards the east, the west, or the north. Do I find the rotation of the head, or the parent Main camera?
The Cardboard class contains a property called HeadRotation which is a Quaternion.
Quaternion crtRot = youCardboardController.HeadRotation;
To use its rotation like you'd in Unity with directional vectors you may simply multiply it by Vector3.forward.
Vector3 lookDir = crtRot * Vector3.forward;
Visualizing the vector in editor might help narrow down issues
void Update () {
// ..
Debug.DrawRay( pos, lookDir * 100, Color.blue );
// ..
}
From here you only need to know where North is, in meaning of the facing vector. Do a Vector3.Angle() and you have the angle between your avatar's and North's vector. You might want to evaluate both vectors with their y axes set to 0.
You could also use Vector3.Dot() (the dot product) to determine how much both vectors look into the same direction.
I had an issue with HeadPosition, which wasn't updated properly. So if you operate from HeadPosition keep in mind it may stick to 0,0,0 .
Take Head.transform.rotation - that's the orientation of the user's head.
I'm not really sure what do you mean by North or West. If the mobile device has a magnetometer, then maybe you could read it's data to determine where North is, but I've never done that
It would be the rotation of the Head object, although the Main Camera usually has the same rotation.
But if you want the direction relative to the real world, that information is not available in the SDK. The compass cannot be used because of the magnet, so there is no way to get the real direction.
Just take the rotation angle of the main camera in the scene. It will gives you the head rotation angles with respect to x, y and z axis.
In GVR based VR scenes the system is internally rotating the camera with respect to our head movements. So it's easy to get the head rotation using main camera rotation angles.
For that,
//local rotation of the Transform of the camera
Camera.main.transform.localEulerAngles.y
//The world Y rotation
Camera.main.transform.rotation.y
I have a screen filled with circles. One circle is the player, one is the enemy, and the others are obstacles. I want the enemy to be able to calculate if there is an obstacle in the path of a straight line from the player to the enemy, so it can adjust accordingly (it is taking place in space, so it is a straight line for jumping from asteroid to asteroid).
Right now, I just turn a random direction when the AI is stuck on an asteroid.
A simple solution could be find the Vector2 between player and enemy (using Vector2.Subtract), and then divide it into smaller vectors or reduce it to a delta that you choose. This can be done normalizing the distance vector and multipling it by a fixed number.
Then simply add that delta to the enemy position and check if the new position collides with an objects (maybe using Rectangle.Contains method), and do this until you reach the player.
I am working on a game, and I currently have objects continuously orbiting around a sphere at a fixed distance. I need to allow the object to bounce off of each other. Does anyone know how I can go about doing this?
I have the collision detection working, and each object has a bounding sphere. I am able to get the point of collision, I just need to take the current rotation vector from each object and get the resulting "bounce" angle (vector to rotate around) and have each object continue orbiting around it's new vector.
Let me know if that doesn't make sense or if you need anything else! I should mention that this is done using Unity3D (I am not using rigidbodies, or the built in physics engine for performance reasons)
Edit:
Here is what I've tried:
public void OnTriggerEnter(Collider collider)
{
// Determine resultant rotation axis
Vector3 collisionNormal = collider.ClosestPointOnBounds(thisTransform.position);
rotationAxis = Vector3.Reflect(rotationAxis, collisionNormal);
}
Here is a link to the Vector3.Reflect() method in the Unity3D docs: Vector3.Reflect()
At this point the objects don't start moving in a new direction they collide and then don't bounce off. They just appear to stop when the collision occurs.