Unity LookAt() function is behaving strangely - c#

So I was testing 2D sprites in my game when I noticed that the LookAt() function was behaving weirdly. I was pointing the sprite towards the camera to achieve a flat look when I noticed that the image wasn't looking the right way.
The sprite I used looked like this (30 seconds in MSPaint)
and this is what it looked like in the editor
However, when I run it the sprite seems to look in some other strange direction not relating to the camera itself.
I just used the standard LookAt function, setting the z value to transform.position.z to limit the way it looks at things (this wasn't the problem, as upon setting it to obj.transform.z I had a similarly wrong transformation.
using UnityEngine;
using System.Collections;
public Transform obj;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.LookAt (new Vector3( obj.position.x, obj.position.y, transform.position.z), Vector3.up);
}
If anyone is willing to give me some pointers of how to fix this, that would be great!

I think this problem may occur if the camera doesn't have rotation matching the rotation of Sprite. If you use for the camera:
transform.LookAt(yourSprite.transform.position, Vector3.up);
and for the sprite:
transform.LookAt(yourCamera.transform.position, Vector3.up);
they will both "LookAt" each other.
If you can't/don't want to rotate the camera, the sprite would have to match the camera rotation, not "LookAt" the camera position. It all depends on camera rotation, and on what you want to achieve.

Related

I am working on a game project on unity and I am stuck at a camera problem

It has two camera angles. First person for engaging gameplay and top-down for 2D game experience. But in top down camera view I can't figure out the rotation of the camera with respect to player.
I wrote the following script for the main(top-down) camera view.
public class FollowPlayer : MonoBehaviour
{
public GameObject player;
private Vector3 offset = new Vector3(0f, 24.953f, -0f);
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}`
I tried
transform.rotation = player.transform.rotation;
but it didn't work since camera is on top of player. If I could somehow do
transform.rotation = player.transform.rotation + X axis 90 degree;
That would be perfect but I don't know how to do that.
If I understand you correctly, you want to follow the player from above with your second camera. Leaving some flexibility, the best option I think would be Unity's built in Transform.LookAt(target) method (LookAt), which automatically rotates an object (in your case the camera) so that it faces the target.
Therefore, you could do something like this in your Update, assuming your script is attached to the Camera. Otherwise substitute transform with Camera.main.transform:
transform.LookAt(player);
Note: If you plan to have your camera fixed above your player at all times, it is sufficient if you perform the LookAt once, e.g. in Start and then attach the camera as a child to the player. If your camera does not move with your player in the world but you want it to focus the player anyway, do do it in Update. Hope I addressed your problem:)
My problem has been resolved. I was trying to rotate the wrong axis. My bad.
mouseInput = Input.GetAxis("Mouse X");
transform.Rotate(Vector3.forward * speed * -mouseInput);
I needed to get mouse input from user and change the Z-axis according to it. Game is working fine now.

Problems trying to rotate my ship to be parallel to the mesh normal its floating on

So I'm making a game where you sail in a pirate ship, I animated a sea in blender and made a script to update the mesh collider so raycasts trigger properly on the animated mesh, so far so good.
now the problem I'm facing is with the boat, so far I have been able to make the boat ride the waves:
// This is the script that handles the riding of the waves.
[SerializeField] private LayerMask m_whatIsSea;
[SerializeField] private float m_offsetFromWaterSurface;
private void Update()
{
// Shoot a raycast from above the water down to detect the height.
RaycastHit _hit;
if (Physics.Raycast(gameObject.transform.position + (Vector3.up * (Mathf.Abs(m_offsetFromWaterSurface * 4))), -Vector3.up, out _hit, m_whatIsSea))
{
Float(_hit);
}
}
private void Float(RaycastHit hit)
{
// Than move the boat to the height.
Vector3 _newPosition = new Vector3(gameObject.transform.position.x, hit.point.y + m_offsetFromWaterSurface, gameObject.transform.position.z);
transform.position = _newPosition;
}
But when I move the ship with a ship controller, it does correctly change its height.
but all attempts at making my ship rotate according to the raycasted mesh normal (the hit.normal in the above code) haven't worked out for me.
I have made attempts that did somewhat work out for me, but the biggest issue in those is that the mesh consisting of big triangles doesn't give me a smooth rotation rather constantly snapping to the normals, which of course isn't good.
So the final result I'm trying to achieve is that my ship rotates so that it's visually going up and down the waves instead of having the front clipping through.
I appreciate any help! I've been trying to come up with a solution for longer than I can admit. :-)
I would try Vector3.RotateTowards.
The 4th argument maxRadiansDelta in the method public static Vector3 RotateTowards(Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta); should allow you to rotate the ship in the hit triangle normal's direction with maxRadiansDelta as a maximum value you can play with to set and make the rotation smooth enough.

Camera follow with a World Space Canvas gets weird result?

I want to follow the camera the player along (just the y axis, but this I will look later) for now I have the following problem:
I have a background image in a seperate canvas (World Space) with my Main Camera attached.
Now if I attach a camera follow script (simply transform.position = Player.transform.position) the background image follows.
This results to the following: Everything falls down.
I tried to use another camera but I don't know if I just did it wrong. I have no idea.
as I said, just:
void update()
{
transform.position = Player.transform.position
}
but the code isn't my problem. I expect that the camera follows the player on the y axis (but not 100% just smoothly a bit) but I will look up for that later
I want that the Background doesn't move. Is there another Way to have them background images as a world space, or something I don't know?
void update()
{transform.position = Player.transform.position}
this will make your camera follow your player whatever his direction.
while u didnt mention any details, I expect the reason why everything is falling bec your mainplayer is falling due to physics . and u need to fix this by adding rigibody to your mainplayer and make sure that any thing he walk on also has colliders.
if u want your camera only to follow player on Y axis only , it should be something like this
void update()
{ float y = player.transfor.position.y;
Vector3 newPos = new Vector3(transform.position.x,y,transform.position.z);
transform.position = newPos;
}
and I suggest you cach your transform varaibles too.
lastly about your image that you dont want it to move, just dont attach it to any moving gameobject and set it to static and it should never move at all.

Unity, Moving object by friction + rotation

I am desperately looking everywhere for a solution to this problem but did not find any possibility yet, maybe you can help me out:
I am making a simple test in which a kind of cylinder can rotate itself and moving on a flat platform by friction. I have rigid body, mesh collider attached already and a script to control the rotation. It can be moving fast or slow depends on its rotation speed.
The script is as follow:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float rollingSpeed;
public float gravity;
// Update is called once per frame
void FixedUpdate()
{
transform.Rotate(rollingSpeed, 0.0f, 0.0f);
GetComponent<Rigidbody>().AddForce(0.0f, -gravity, 0.0f);
}
}
The problem is when I run the Play mode, this cylinder is rotating itself but staying in the same position! (in fact it is moving back and forth very slightly), I really dont know what is the cause, I tried to increase the friction parameters, add physical materials, and even adding a second force downward (like gravity) but it doesnt work.
Can anyone please have a solution for this? Thank you guys so much!
Rotate is just transform eular coordinate without any force, use AddTorque instead for physical movement.
For example,
GetComponent<Rigidbody>().AddTorque(new Vector3(1, 0, 0) * rollingSpeed * Time.deltatime);
Read more, Unity Doc.
To add a tips about basic physics on Unity.
Please remember when you are working with Transform, it means NO physics. You are just changing its position and rotation.
To work with physics, is always Rigidbody.

most efficient way to get a very smooth player movement in unity5

So I am making a simple 2d endless mobile game. In the game, the player object (spaceship) moves upwards continuously and then the player can use either left or right to move the player to avoid obstacles.
As a newbie I am finding it very difficult to achieve a very smooth motion in the player movement. I have watched many tutorials including the unity official tutorials about moving an object. They all use simple techniques like:
rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed in the fixedupdate function
or transform.Translate (velocity * Time.deltaTime * speed) in the update function
or rigidBody.MovePosition (rigidbody.position + velocity * Time.fixedDeltaTime) in the fixed update or
just just changing the transform.position over time in the update function.
But none of these techniques or code that I have used have helped me to achieve that very smooth motion in the player movement that I want. No matter what I try I still get lags in the player movement. I have also tried switching the rigidbody.iskinematic on and of and changing the rigidbody interpolation but I am still not able to achieve a smooth movement in in 2d games that we see such as ios games shredd or split the dot. I thought that it might be my computer that was very slow or something that is why I am not getting a smooth movement but I transported my project onto my friends computer which is twice as fast and I still have the same results. I also striped all that decided to erase all the code that is in the player controller scripts and just focus on the code for moving the player but the results has not changed.
I am thinking that it is because I am just using a very simple and inefficient code to move the player or it might have something to do with changing some settings in unity. So the question is what is the most efficient way to achieve a very smooth player movement in unity. (Codebase and unity settings.)
Currently I am just using rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed to move the player and I have made the camera a child object of the player for simplicity.
Thank you.
I would use Vector3.Lerp to interpolate the transform.position. This essentially mathematically smooths out the translation between the two positions.
Something else I've experienced is that the editor is sometimes more laggy than the end product, so I recommend building the game and testing it out to see if that is the case.
Finally, if you are using transform.position to move the object, ensure that the numbers are fairly small. Big numbers obviously make the object jump around a lot more.

Categories