noob here.
I am currently using a tutorial to make my first little 2d platformer.
With the use of a script, my character can move left and right. The issue I am having is
getting the sprite to jump.
Below is my code:
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController2D Controller;
public float RunSpeed = 40f;
bool Jump = false;
float horizontalMove = 0f;
// Update is called once per frame
void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * RunSpeed;
if (Input.GetButtonDown("Jump"))
{
UnityEngine.Debug.Log("This works");
Jump = true;
}
}
private void FixedUpdate()
{
Controller.Move(horizontalMove * Time.fixedDeltaTime, false, Jump);
Jump = false;
}
}
The debug line does execute in the console my the Code registers my press of the space button, however, nothing happens to the little man on screen.
I hope someone can help.
Many Thanks,
Ellis
the value you use in Controller.Move() to specify the force of the jump seems to be 0.
If you change horizontalMove to a public float you can assign a value to it in the unity editor or you can assign a value in the script.
Good luck.
EDIT:
Sorry, Immortality is right. You already set horizontalMove.
Input.GetAxisRaw can be -1,0 or 1. So horizontalMove can become -40, 0 or 40. Because you multiply in your controller arguments with Time.deltaTime - and deltaTime often being around 0.005 - your argument becauses roughly (-)0.2. I don't know what your controller does with that value but I guess that's the reason why you don't see anything. The value is just to small
Related
I'm new to unity and I'm trying to follow this tutorial: https://www.youtube.com/watch?v=7iYWpzL9GkM&t=1600s
But when I do the code at 42:00 and compile my character wont move at all. I wont to believe I did everything exactly as the video explains but I cant figure out how to fix it.
Here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine;
//Take and handle input and movement from the character
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 1f;
public float collisionOffset = 0.05f;
public ContactFilter2D movementFilter;
Vector2 movementInput;
Rigidbody2D rb;
List<RaycastHit2D> castCollisions = new List<RaycastHit2D>();
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void FixedUpdate(){
//If movement input is not 0, try to move
if(movementInput != Vector2.zero){
bool success = TryMove(movementInput);
if(!success){
success = TryMove(new Vector2(movementInput.x, 0));
}
if(!success){
success = TryMove(new Vector2(0, movementInput.y));
}
}
}
private bool TryMove(Vector2 direccion){
//Check for Potencial Collisions
int count = rb.Cast(
direccion, // X and Y values between -1 and 1 that represent the direction from the body to look for collision
movementFilter, // The setting that determines where a collision can occur on such as layers to collide with
castCollisions, // Lists of collisions to store the found collisions into after the Cast is finished
moveSpeed = Time.fixedDeltaTime + collisionOffset); // The amount to cast equal to the movement plus an offset
if(count == 0){
rb.MovePosition(rb.position * direccion * moveSpeed * Time.fixedDeltaTime);
return true;
} else{
return false;
}
}
void OnMove(InputValue movementValue){
movementInput = movementValue.Get<Vector2>();
}
}
If anyone can help I really appreciate it.
Input System: version 1.3.0
Visual Studio Code Editor: version 1.2.5
Test Framework: version 1.1.33
Unity: version 2021.3.7f1
Your should change direccion to direction in TryMove.
You should make sure you have all your values in the inspector assigned to the according thing. eg. rb should be assigned to your character and your character should have the rigidBody attached to it.
Hope this helps, tell me if it still doesn't work.
I have a weird problem and cant seem to fix it. I was creating my first game in Unity and I was testing around a bit after creating a movement system and whenever I touch another object (it doesn't matter if it has a rigid body or not), my player suddenly starts moving on its own. I have a video showing what exactly happens: https://youtu.be/WGrJ0KNYSr4
I have tried a few different things already and I determined that it has to do something with the physics engine because it only happens when the player isn't kinematic. So, I tried to increase the solver iterations for physics in the project settings, but the bug was still happening. I looked for answers on the internet, yet the only thing I found was to remove Time.deltaTime, though it still doesn't work. I have found that it seems to happen less though when the player is moving fast.
I would really appreciate if somebody could help me with this. This is my first real game and I'm creating it for the Seajam that's happening on itch.io.
Here is the code for my playercontroller script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float playerSpeed = 3f;
private Rigidbody playerRb;
public GameObject cameraRotation;
// Start is called before the first frame update
void Start()
{
playerRb = GetComponent<Rigidbody>();
}
float verticalSpeed;
float horizontalSpeed;
bool isOnGround = true;
// Update is called once per frame
void Update()
{
//get controlled forward and backward motion
verticalSpeed = Input.GetAxis("Vertical");
transform.Translate(Vector3.forward * playerSpeed * verticalSpeed * Time.deltaTime);
//get controlled sidewards motion
horizontalSpeed = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * playerSpeed * horizontalSpeed * Time.deltaTime);
//lock the rotation of the player on the z and x axis
transform.eulerAngles = new Vector3(0, cameraRotation.transform.eulerAngles.y, 0);
//when pressing space jump and prevent air jump
if (Input.GetKeyDown(KeyCode.Space) && isOnGround)
{
playerRb.AddForce(Vector3.up * 10, ForceMode.Impulse);
isOnGround = false;
}
}
//check if the player is on the ground
private void OnCollisionEnter(Collision collision)
{
isOnGround = true;
}
}
Try not locking the player's rotation by script, maybe it is causing the problem due to gimbal lock. Instead go to your player's RigidBody->Constraints and then lock it.
You can read more about it here https://fr.wikipedia.org/wiki/Blocage_de_cardan
I am having this problem that I don't know how to solve, I have a moving object that return to a position if a condition is verified, but it seems like it is working sometimes, but sometimes it is not ..
Here is my script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingDes : MonoBehaviour {
private float speed = 5f;
Transform trn;
//-37.6914
//62.32123
// Use this for initialization
void Start() {
trn = GetComponent<Transform>();
}
// Update is called once per frame
void Update() {
transform.Translate(Vector3.back * (speed * Time.deltaTime));
if(transform.position.z <= -37.6914){
Vector3 newPosition = new Vector3(17.5f,125.7f,165.32123f);
trn.position = newPosition;
}
}
}
The problem is that I can see in my Unity editor that the position is different from what I have set, and I don't understand from Where those values came from, I did not write them for sure.
Any help would be much appreciated.
You are moving object with transform.Translate every frame, so immediately after setting up new position, your object is moved again. Notice that in your case trn, and transform, refers to the same Transform component.
Why don't you change your trn.position= to transform.position= I don't think you need GetComponent<> for transform component of the current gameObject. Or maybe related to relativeTo parameter of .Translate method.
I have been following a tutorial on 2D Player Controller in Unity (It's 'Live Training 16 Dec 2013 - 2D Character Controllers' video).
I was able to implement everything the tutorial showed successfully with some edits to make it work in Unity 5. Afterwards, I decided to play around with it so that I can gain a better understanding. One thing I tried to do was changing the jump height when pressing the Space key. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RobotControllerScript : MonoBehaviour {
public float maxSpeed = 10f;
bool facingRight = true;
Animator anim;
bool grounded = false;
public Transform groundCheck;
float groundRadius = 0.2f;
public LayerMask whatIsGround;
public float jumpForce = 700f;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
anim.SetBool("Ground", grounded);
//vSpeed = vertical speed
anim.SetFloat("vSpeed", GetComponent<Rigidbody2D>().velocity.y);
float move = Input.GetAxis("Horizontal");
anim.SetFloat("Speed", Mathf.Abs(move));
GetComponent<Rigidbody2D>().velocity = new Vector2(move * maxSpeed,
GetComponent<Rigidbody2D>().velocity.y);
if (move > 0 && !facingRight)
{
Flip();
}
else if (move < 0 && facingRight)
{
Flip();
}
}
void Update()
{
if(grounded && Input.GetKeyDown(KeyCode.Space))
{
anim.SetBool("Ground", false);
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, jumpForce));
}
}
void Flip()
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Looking at the code and the tutorial explanations, jumpForce is the variable that controls how high the character will jump (force applied). So, I changed 700f to a 5f. I expected the character to make a really small jump, but this was not the case. It jumped at the same height as 700f.
public float jumpForce = 700f;
After playing around with the code, I was able to have the expected result by removing the 'public' next to jumpForce. Other ways to fix this was setting it to private or static. I remember I had a similar problem when making a temperature widget on QT Creator. I had to set a variable to static or else it would not return to the default value after C to F conversion, but I don't remember exactly why.
Can anyone explain why 'public' does not work and why a private/static/nothing might? What is the best/efficient solution for this problem? Thank you very much.
When a field is public (or serializable), it is shown in inspector. When it is shown in inspector, you tweak it's value, a you expect the tweaks you make to the value, in the inspector, to be preserved between play mode runs.
When you declare a variable in the code, you may specify an initial value, like this:
public float jumpForce = 700f;
So, the first time this object gets inspected, after created, it has a reasonable value. Then, you tweak and choose a better value (or back to the same, whatever). That's the value you preferred! You want the object to keep functioning like this while you go ahead and finish making your game.
So, once a field is tweaked in Inspector, it doesn't respect the initial value you hardcoded anymore, and that's usually what everyone want. Imagine how annoying would be if everytime you make a change in your class, all the tweaked fields got back to the initial hardcoded value...
If a field was previously public, and then you make it private (or hidden in inspector by any mean), then the hardcoded initial value will stand.
But, what if I really want my object to get back to it's initial/default configuration? That's why the Reset method and the reset button in inspector were made!
I have just updated Unity to version 5.2.1 from 5.0.0 this morning and I experienced a few problems. After Unity translated the game to work for the new version, I tested the game. Everything worked fine, except that when I shot a bullet in my game, they would stick to the walls instead of bouncing off of them, but only at certain angles and distances. It was like the bullet was so fast that it skipped hitting the collider and got stuck inside of the collider. That would make a little bit of sense, but the weird part is that I have a C# script for slow motion in the game. Whenever I turn the slow motion on and then turn it off again, the problem with bullets sticking goes away. I cannot seem to figure out what is causing the problem and it definitely wasn't there before I updated the software. Can anyone help me out with this? Thanks. I'll post the bullet script and the slow motion script below. The bullet is instantiated inside the player script by the way.
Bullet Script:
using UnityEngine;
using System.Collections;
public class Bullet : MonoBehaviour {
public float bulletSpeed;
public float bulletOpacity;
public bool fadeOut;
Animator anim;
Rigidbody2D rigidbod;
SpriteRenderer spriterend;
public GameObject player;
public float aimRotation;
// Use this for initialization
void Start () {
anim = GetComponent<Animator> ();
rigidbod = GetComponent<Rigidbody2D> ();
spriterend = GetComponent<SpriteRenderer> ();
rigidbod.velocity = transform.right * bulletSpeed;
rigidbod.gravityScale = 0;
bulletOpacity = 1;
}
// Update is called once per frame
void Update () {
Destroy (gameObject, 3f);
spriterend.color = new Color (1f, 1f, 1f, bulletOpacity);
if (fadeOut == true)
bulletOpacity -= 0.03f;
if (bulletOpacity <= 0)
Destroy (gameObject);
aimRotation = player.GetComponent<Player> ().aimRotation;
}
void OnTriggerEnter2D (Collider2D bulletHit) {
/*if (bulletHit.gameObject.layer == LayerMask.NameToLayer ("vulnerableLayer")) {
}*/
rigidbod.gravityScale = 1;
rigidbod.drag = 1;
fadeOut = true;
}
}
Slow Motion Script:
using UnityEngine;
using System.Collections;
public class SlowMotion : MonoBehaviour {
public float currentLongevity = 0f;
public float slowAmount = 0.2f;
public float normalTime = 1f;
public float slowLongevity = 0.4f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown (1)) {
Time.fixedDeltaTime = 0.0f * Time.timeScale;
if (Time.timeScale == normalTime)
Time.timeScale = slowAmount;
}
if (Time.timeScale == slowAmount) {
currentLongevity += Time.deltaTime;
}
if (currentLongevity > slowLongevity) {
currentLongevity = 0;
Time.timeScale = normalTime;
}
}
}
Since you indicated that the 'weird' bullet behavior ceases after the SlowMotion script is run, I would suggest that the issue has to do with setting Time.fixedDeltaTime as you are doing in the Update() method of the SlowMotion script. This is also supported by your later comment that the 'weird' behavior no longer appears when you set the rigidBody2D's collision detection to continuous (the bullet's RigidBody2D I assume).
Continuous RididBody2D collision detection enables determining if contact occurred between updates, where as Discrete collision detection registers a collision during a physics update. In your SlowMotion script, the following line (in the Update() method) sets fixedDeltaTime to zero:
Time.fixedDeltaTime = 0.0f * Time.timeScale;
Since Time.fixedDeltaTime is the interval in seconds at which physics and other fixed frame rate updates are performed, there must be some minimum value at which the frame rate is realistically run, (0.0 cannot be an actual frame-rate update interval). When Time.fixedDeltaTime == 0.0, Unity may use a default minimum value or use this to indicate that frame updates run as often as possible, (though I have not tested this). Since the Bullet script calls Update() rather than FixedUpdate(), there is no guarantee that the actual interval between the frame updates is uniform. I suspect that when you run the SlowMotion script, and set Time.fixedDeltaTime to 0.0, Unity runs with the smallest possible frame update interval and following this, it does render the expected bullet behavior.
One way to test this would be to set your initial Time.fixedDeltaTime to 0.0 in the editor (and your collision detection behavior back to discrete for the bullet's RididBody2D).
To set Time Manager fixedDeltaTime in the editor: main menu -> Edit -> Project Settings -> Time
If you find a fixedDeltaTime that works, you can set this in the editor and retrieve the initial value in your SlowMotion script in the Awake() method to initialize the base fixedDeltaTime. I would not recommend using fixedDeltaTime == 0.0 since there is no indication in the documentation of a consistent behavior for a time interval of 0.0 and it may be bound more to the underlying hardware and could result in more unexpected behavior.
Hope this helps, cheers!