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.
Related
I'm making a game which involves rotating around a point shooting enemies before they reach said point, in 2D. However, as the enemies are going to be spawned in random places around the game, I need to make them rotate towards the centre to start moving in that direction. Here is the code that doesn't function properly:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Rigidbody2D rb;
//this is the enemy, by the way
public Transform follow;
public void Start()
{
transform.LookAt(Vector2.zero);
rb.velocity = follow.up; //'up' worked in my bullet script for heading in the direction the player was facing
}
}
Instead of the knob rotating and slowly moving towards the point, the knob weirdly elongates and then begins to move towards the top of the screen, but at a slight angle. It's probably a stupid mistake, as I've only been writing in C# and using Unity for about a week.
However, any help would be greatly appreciated!
Edit: After clarification, this is my answer:
You should use Vector3.MoveTowards.
void Update ()
{
enemy.transform.position = Vector3.MoveTowards(enemy.transform.position, point.transform.position, speed * Time.deltaTime);
}
I would recommend attaching this to your enemy game object and replacing enemy.transform.position; with gameObject.transform.position;. This way you can make an enemy prefab later on and easily spawn as many as you need.
https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html
Sorry if I don't understand fully, but you want the enemys to rotate and move towards the center of the screen?
If so, you can use transform.Rotate(rotation * Time.deltaTime); to rotate the enemys and transform.Translate(vector * Time.deltaTime);to move them towards a point.
Add the game object you want to move to the method. Eg, if this were going to be attached to your enemies script you would write gameObject.transform.Rotate(rotation * Time.deltaTime);.
If you wanted the enemys to circle around something you could create a 'point' game object then attach the rotate script to it. Then make the enemies children of that object so they rotate with it. Then, put the translate script on the enemys so they move towards the point.
Hope this helps!
https://docs.unity3d.com/ScriptReference/Transform-rotation.html
https://docs.unity3d.com/ScriptReference/Transform.Translate.html
Try this. Transform.LookAt might not be working for 2d. See this for similar example.
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Rigidbody2D rb;
public float speed = 1f;
public Transform follow; //this is the enemy, by the way
public void Start()
{
//depending how your enemy points (is its forward direction x axis or y axis) you should either use transform.right or transform.up
transform.right = follow.position - transform.position;
// or use transform.up = follow.position - transform.position;
rb.velocity = transform.right * speed; // change transform.right to transform.up if you use transform.up above.
}
}
I'm trying my first test-game with Unity, and struggling to get my bullets to move.
I have a prefab called "Bullet", with a RigidBody component, with these properties:
Mass: 1
Drag: 0
Angular drag: 0,1
Use grav: 0
Is Kinematic: 0
Interpolate: None
Coll. Detection: Discrete
On the bullet prefab, I have this script:
public float thrust = 10;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.AddForce(transform.forward * 100, ForceMode.Impulse);
}
On my playerController script (not the best place for this, I know):
if (Input.GetAxisRaw("Fire1") > 0)
{
var proj = Instantiate(projectile, transform.position, Quaternion.identity);
}
When I click my mouse, the bullet gets created, but doesn't move. I've added velocity to the rigidbody, which works, but I can't get it to move in the right direction. After googling around, it seems I need to be using rigidBody.AddForce(), which I did, but still can't get my bullet to move.
I've seen the other solution, but this did not work for me either.
Any advice would be appreciated.
Screenshot:
When you're working with 2D in Unity, the main camera basically becomes an orthographic camera (no perspective effects) looking sideways at the game scene along the z-axis. Incidentally, the "forward" direction of a non-rotated object is also parallel to the z-axis.
This means that when you apply a force along transform.forward, you're sending the object down the z-axis - which will not be visible to an orthographic camera looking in the same direction. The quick fix here would be to use a direction that translates to an x/y-axis movement, like transform.up or transform.right.
As derHugo also mentioned in the comments, you might want to look into using Rigidbody2D. There are some optimizations that will allow it to behave better for a 2D game (though you may not notice them until you scale up the number of objects).
So I've designed a custom HP bar and aligned it where I'd like it to be as well as how I'd like it to look.
However, when I press play (Not full screen mode, haven't even tested for that)either the image background slides slightly right or the green filler image slides to the left.
I have no idea why it's doing this or how to fix it. I'm willing to offer whatever information you require such as code or screenshots of the inspector.
This is a screen shot of the bar as it is in the sceneview canvas.
As you can see when the Play isn't pressed the bar functions normally. The above pic is Half-Full. The below image is Empty.
Part 2 of the issue:
I'm also having trouble with the HP bar rotating properly with the player.
However, when I turn left or right or face up:
]9
So you can see the HP bar doesn't properly rotate with the player's movement; although it does follow perfectly, the bar doesn't rotate accordingly. I can provide some movement code and the code I use to track the position of the player. What I have done was created a sphere and attached it to the player. I then attached the script for tracking the player onto that sphere. I then removed the mesh render and box collider of the sphere.
Health Bar Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PHealth : MonoBehaviour {
[Header("HP Bar Images")]
[SerializeField]
private Image HpBarBG;
[SerializeField]
private Image HpBarFillBar;
private float imgFill = 1;
void Update () {
FillBar()
}
private void FillBar(){
HpBarFillBar.fillAmount = imgFill;
}
}
Player Movement Script
public GameObject player;
public Vector3 localscale;
// public Transform start, end;
[SerializeField]
private float speed = 5;
void Start () {
}
// Update is called once per frame
void Update ()
{
/*
******** RAYCAST TO DETECT WALLS BELOW *******
*/
// WallDetection(); //Cast ray to detect walls
/*
********* MOVEMENT CODE BELOW *********
*/
if (Input.GetKey(KeyCode.W)|| Input.GetKey(KeyCode.UpArrow)) // Move
Forward
{
player.transform.Translate(Vector2.up * speed * Time.deltaTime,
Space.World);
transform.eulerAngles = new Vector2(0, 180);
}
}//End of class
I'd recommend adding your code to your question so we have the full picture. Before you do that, I can only give you some recommendations and suggestions. I'll amend this answer, so it becomes a real answer, afterwards.
In the mean time, what type of canvas are you using? Judging from the hierarchy, I'd imagine it's in either of the screen space modes. Have you considered a world-space canvas parented to your player? I believe it'll naturally rotate in the way that you want it to. Can the players zoom in and out, and is the player character's rotation fixed to 90-degree increments?
In addition, are you sure you want the healthbar to rotate? To be upside down? Won't it be a better idea to keep it fixed in a regular position, above the character's sprite, even if that's technically "below" the character at the time?
Finally, if you don't mind me asking: why Unity 5? It's been a couple of major releases after it, and 2018 is almost at its cycle's end. Though to be fair, I don't know if the version will make any difference for this, so I'm just being curious.
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.
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.