I have
Vector3 PlayerPosition = new Vector3(0,0,0);
Matrix JetztMatrix = Matrix.CreateRotationX(pitch) * Matrix.CreateRotationY(yaw);
ef.View = Matrix.CreateLookAt(PlayerPosition, Vector3.Transform(new Vector3(?1,?2,?3), JetztMatrix) + PlayerPosition, new Vector3(?4,?5,?6));
Somehow I always hit some threshold so the screen rolls instead of rotates.
So for instance I give -180° to +180° as yaw. This leads to one turn, but not on a straight "line". As I said, it moves then the screen rolls and it moves again.
How do I determine ?1 to ?6
ef.View = Matrix.CreateLookAt(PlayerPosition, playerPosition + JetzMatrix.Forward, Vector3.Up);
The Vector3.Up will keep the camera from rolling. It's hard to understand exactly what you want to end up with based on your question. If this doesn't solve your issue or creates some other undesirable motion, please describe your desired functionality in more detail.
Related
So what I need is to get the Camera.main.transform.position in front of the camera depending on its direction. I have searched everywhere but for some reason I just can't find the solution.
I tried using transform.forward in a very ill-thought-out way but that didn't work. Nothing I am doing seems to be working.
Basically just add the direction and distance to the given position:
// In general should cache this reference as "Camera.main" is quite expensive
var camera = Camera.main.transform;
var position = camera.position + camera.forward * desiredDistance;
Hey stackoverflow Community,
First of all:
I'm still very new about programming with C# and Unity.
My question:
I'm working on an idea for a Movement of a Cube.
It is planned that the cube will move forward by pressing a key (W-Key). But it shouldn't just move forward. It should jump forward to the next point. So always plus 1 of its axis into which it should go. Accordingly, it is only intended to go forward, right, down, left. He won't be able to jump over behind. You should also see that the cube jumps in the respective direction, so it should not teleport itself. :D
Does anyone have an idea how I can realize this movement?
I am very much looking forward to your ideas.
(Sorry if my English is not so good, my English not the best. ^^)
best regards
xKarToSx
So, in order to understand movement, it's best to first understand Vectors in Unity. Since you want to be moving the cube in the forward direction, I'm going to assume this is a 3D game, in which case you want to use a Vector3.
A Vector3 has three components: X, Y, and Z. Each component is tied to an axis. In simple terms, X is tied to left and right, Y is tied to up and down, and Z is tied to forward and back. So, Vector3 position = new Vector3(0, 1, 2); will be a vector that is 1 unit above and 2 units in front of the starting position.
Assuming you've attached this script to the cube you want to move, you can track its position with transform.position. So, if you want to move the cube one unit forward, your code would look something like this:
if(Input.GetKeyDown(KeyCode.W)) // This code will activate once the user presses W.
{
transform.position += new Vector3(0, 0, 1);
}
That will move the cube one unit forward in the Z direction. However, you don't want it to teleport, you want to see it move, correct? In that case, you want to check out Unity's Vector3.Lerp function. Basically, you would use it to smoothly transition an object between two defined positions. You'll need to implement a timer and a for loop in order to make this work correctly.
So, to summarize, for moving one unit forward in the Z direction, your code would look something like this:
if(Input.GetKeyDown(KeyCode.Z))
{
float startTime = Time.time; //Time.time is the current in-game time when this line is called. You'll want to save this to a variable
float speed = 1.0f; //The speed if something you'll want to define. The higher the speed, the faster the cube will move.
Vector3 startPosition = transform.position; //Save the starting position to a different variable so you can reference it later
Vector3 endPosition = startPosition + Vector3.forward; //Vector3.Forward is equivalent to saying (0, 0, 1);
float length = Vector3.Distance(startPosition, endPosition); //You'll need to know the total distance that the cube will move.
while(transform.position != endPosition) //This loop while keep running until the cube reaches its endpoint
{
float distCovered = (Time.time - startTime) * speed; //subtracting the current time from your start time and multiplying by speed will tell us how far the cube's moved
float fraction = distCovered / length; //This will tell us how far along the cube is in relation to the start and end points.
transform.position = Vector3.Lerp(startPosition, endPosition, fraction); //This line will smoothly transition between the start and end points
}
}
I hope this helps you. This is my first time answering a question so sorry if I got some things wrong/it's not the most optimized. Good Luck!
I have my Building System almost finished; the problem is when I debugged my Physics.OverlapBox(), by using a Gizmos.DrawWireCube() with the code shown below:
void OnGizmosDraw()
{
Gizmos.matrix = Matrix4x4.TRS(transform.position + boundingOffset, transform.rotation, boundingExtents);
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
}
I saw the problem but I will show it in an image, since I am kind of struggling to explain.
I have thought of a solution but I could not find the equations and what method it is. Basically, there is an Original Vector to which an Offset will be added (if defined) and have it's Final Vector affected by Rotation. It is explained more in another.
Maybe it is a trigonometry based calculation. I hope you could find how to do it.
Thanks in advance.
Ok if I understand you correctly this time the issue is that your offset works as long as the transform isn't scaled or rotated.
The reason is that
transform.position + boundingOffset
uses plain worldspace coordinates. As you can see the offset from orange to red dot is exactly the same (in world coordinates) in both pictures.
What you rather want is an offset relative to the transform position and scale. You can convert your boundingOffset to local coordinates relative to the transform by using TransformPoint
Transforms position from local space to world space.
So instead use
Collider[] colliders = Physics.OverlapBox(transform.TransformPoint(boundingOffset), boundingExtents / 2, blueprint.transform.rotation);
What it does is basically
transform.position
+ transform.right * boundingOffset.x * transform.lossyScale.x
+ transform.up * boundingOffset.y * transform.lossyScale.y
+ transform.forward * boundingOffset.z * transform.lossyScale.z;
Alternatively
A bit more maintainable approach I often use in such a case is not providing boundingOffset via a hardocded/field vector but instead simply use a child GameObject e.g. called OffsetPivot and place it in the scene however you want. Since it is a child of your transform it will always keep the correct offset when you rotate/scale/move the parent.
Then in the code I would simply do
[SerializeField] private Transform boundingOffsetPivot;
...
Collider[] colliders = Physics.OverlapBox(boundingOffsetPivot.position, boundingExtents / 2, blueprint.transform.rotation);
I want a sprite to always face the camera, except in the Z-Axis. My sprites keep tipping left or right when I move the camera, and I can't have that.
I have been googling this for hours. I've tried transform.LookAt or Quaternion.LookRotation and manually setting the z to 0, but for whatever reason the z keeps adjusting. I've seen and tried so many solutions that feel like they should work but just don't. If it matters, my sprite is a child of another object, but trying localRotation doesn't work either. Freezing rigidbody constraints also has no effect.
The most accurate I can get it is this:
public class Billboard : MonoBehaviour
{
GameObject cam;
float minDist;
// Start is called before the first frame update
void Start()
{
cam = GameObject.Find("Main Camera");
}
// Update is called once per frame
void LateUpdate()
{
//Scale
minDist = cam.GetComponent<CameraOrbit>().distanceMin;
transform.localScale = new Vector3(1f, 1f, 1f) * (cam.GetComponent<CameraOrbit>().distance - minDist) * 1.01f / 3;
//Direction
transform.LookAt(cam.transform.position);
Vector3 rot = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);
}
}
With this I can get the sprite to face the camera, but the z axis refuses to stay at zero.
Special thanks to StarManta for answering this question on the Unity Forums.
"OK, I think I see what's happening. Them looking like they're rotated is, I think, an illusion; I think they really are accurately pointing at the camera and right-side-up. But, you're treating the camera as if it has a round/fisheye projection, when it really has a rectilinear projection. Usually this doesn't matter but in this case it does. It's hard to explain exactly how this affects this, but the upshot is that, when things that are on either side of the center of the screen are set to "look towards" the camera, they actually appear to be rotated around their Y axes.
The solution to this is actually annoyingly simple: don't set the rotation to look at the camera, set it to be the same as the camera."
transform.rotation = cam.transform.rotation;
Have you tried rotation constraints?
https://docs.unity3d.com/Manual/class-RotationConstraint.html
I had a similar problem, where I wanted some 3d text to always look up, but rotated to the camera.
What worked for me was setting the undesired euler components to zero after applying the lookat rotation.
In your case, it would be something like this.
transform.LookAt(cam.transform.position);
var rot = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);
In case you need another z value, just replace the 0.
I thought it would be simple as:
Vector3 point = Vector3.Transform(originalPoint, worldMatrix);
But apparently not... It make's the point's numbers shoot into the thousands.
Basically, what I'm trying to do is creating a collision system and every two points in this system is a line, so basically I want to collide lines. I want the lines to be able to scale, rotate, and translate based on a world matrix (so that the collision lines are in tune with the object's scale, rotation, and translation).
I've been trying for hours now and I can't seem to figure it out. I've tried multiplying by the View Matrix as well and while that is the closest to what I want, it seems to switching between two sets of numbers! It would be perfect if it stayed with the one set, I have no idea why it keeps changing...
Any help, please? :(
Edit: To add a little, I'm constantly updating the points in an Update call. But I don't know if that would change anything, either way the points = originalpoints first.
Steve H:
One line would have two points, so:
originalPoint[0] = new Vector3(-42.5f, 0f, 0f);
originalPoint[1] = new Vector3(42.5f, 0f, 0f);
point[0] = Vector3.Transform(originalPoint[0], worldMatrix);
point[1] = Vector3.Transform(originalPoint[1], worldMatrix);`
At first, point[0] & [1] equals the same as originalPoint[0] & [1]. But, the moment I move my player even just a few pixels...
point[0] = (-5782.5f, 0f, 0f)
point[1] = (-5697.5, 0f, 0f)
The player's position is -56.0f.
My worldMatrix goes as:
_world = Matrix.Identity // ISROT
* Matrix.CreateScale(_scale) // This object's scale
* Matrix.CreateFromQuaternion(_rotation) // It's rotation
* Matrix.CreateTranslation(_offset) // The offset from the centre
* Matrix.CreateFromQuaternion(_orbitRotation) // It's orbit around an object
* _orbitObjectWorld // The object to base this world from
* Matrix.CreateTranslation(_position); // This object's position
The objects display properly in graphics. They scale, rotate, translate completely fine. They follow the orbit's scale, rotation, and translation too but I haven't tested orbit much, yet.
I hope this is enough detail...
Edit: Upon further research, the original points are also being changed... :| I don't get why that's happening. They're the exact same as the new points...
I figured out my problem... -_-
So, after I create the line points, I do this at the end:
originalLines = collisionLines;
collisionLines & originalLines are both Vector3[] arrays.
I guess just by making one equal the other, it's like they're the exact same and changing one changes the other... that is something I did not know.
So I made this function:
void CreateOriginalPoints()
{
_originalPoints = new Vector3[_collisionPoints.Length];
for (int i = 0; i < _collisionPoints.Length; i++)
_originalPoints[i] = _collisionPoints[i];
}
And this solves the problem completely. It now makes complete sense to me why this problem was happening in the first place.
Thanks a lot Donnie & Steve H. I know you two didn't answer my question but it got me to poke around even deeper until I found the answer.