Why won't my rigid body stop moving on collision? - c#

I'm new to Unity.
Below is my simple character controller C# script. I'm using 3d cubes with box colliders and rigid bodies as both my walls and player. Currently when my player comes into contact with a wall, it just keeps going.
Why is my script not working?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour {
public float speed = 180;
private Rigidbody rig;
private Vector3 movement;
// Use this for initialization
void Start () {
rig = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
if (rig.velocity.magnitude <= 0)
{
if (Input.GetKeyUp("up"))
rig.velocity = new Vector3(0, 0, rig.position.z * speed );
else if (Input.GetKeyUp("down"))
rig.velocity = new Vector3(0, 0, rig.position.z * speed * -1);
else if (Input.GetKeyUp("right"))
rig.velocity = new Vector3(rig.position.x * speed, 0, 0);
else if (Input.GetKeyUp("left"))
rig.velocity = new Vector3(rig.position.x * speed * -1, 0, 0);
}
}
void OnCollisionEnter(Collision collision)
{
rig.velocity = Vector3.zero;
}
}

The script above works... My y position was higher than the position of my walls so there was never any collision. I feel dumb. Leaving post up as a reminder of my failure.

Related

error with movement in unity following a tutorial

i'm trying to make a game on unity using C# for a games dev course. the course is: https://www.youtube.com/watch?v=b8YUfee_pzc and at 51:55 is where i am experiencing the error. the error is NullReferenceException: Object reference not set to an instance of an object player.FixedUpdate () (at Assets/scripts/player.cs:32)
i have checked and it seems to be letter by letter (including caps) perfect, unless i'm jsut stupid.
it may be because of outdated code, something in unity or me just copying something down wrong. anyhow, here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(BoxCollider2D))]
public class player : MonoBehaviour
{
private BoxCollider2D boxCollider;
private RaycastHit2D hit;
private Vector3 moveDelta;
private void start(){
boxCollider = GetComponent<BoxCollider2D>();
}
private void FixedUpdate()
{
float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");
// reset move delta
moveDelta = new Vector3(x, y, 0);
// swap sprite direction
if(moveDelta.x > 0)
transform.localScale = Vector3.one;
else if (moveDelta.x < 0)
transform.localScale = new Vector3(-1,1,1);
hit = Physics2D.BoxCast(transform.position, boxCollider.size, 0, new Vector2(0, moveDelta.y), Mathf.Abs(moveDelta.y * Time.deltaTime), LayerMask.GetMask("actor", "blocking"));
if (hit.collider == null)
{
transform.Translate(0, moveDelta.y * Time.deltaTime, 0);
}
hit = Physics2D.BoxCast(transform.position, boxCollider.size, 0, new Vector2(moveDelta.x, 0), Mathf.Abs(moveDelta.y * Time.deltaTime), LayerMask.GetMask("actor", "blocking"));
if (hit.collider == null)
{
transform.Translate( moveDelta.x * Time.deltaTime, 0, 0);
}
}
}```
Found a comment on that video that worked for me: "changing "private BoxCollider2D boxCollider;" to "public BoxCollider2D boxCollider;" then dragging the box collider in to the tab on the script under your npc"

When I want my Player to jump he is flying (Unity2d)

Hello I want to make my first game in 2D but when i want to Jump, my Player is flying and he doesnt come back to the ground. I don't know why it doesnt work. Hopefully someone can help me. Thank you. Here is my Code:
using UnityEngine;
using System.Collections;
public class Move2D : MonoBehaviour
{
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
movement = Input.GetAxis("Horizontal");
if (movement > 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
}
else if (movement < 0f)
{
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
}
else
{
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump"))
{
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
}
}
}
You set the y velocity on jump but never set it back to anything else. I suggest that for jump you use rigidBody.AddForce:
rigidBody.AddForce(transform.up * jumpSpeed, ForceMode2D.Impulse);
I also have to say that your first if..else if...else seems to be redundant.
If movement > 0, you do X, is movement is < 0, you do exactly the same, and
if movement == 0, you still do the same even tho you write it differently. (If movement == 0 then movement * speed is also 0). So you could just state that
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
without using if at all.
edit: I accidentally wrote wrong line for what to use, fixed it now.
edit2: So after both of these changes your Update function would be like:
void Update()
{
movement = Input.GetAxis("Horizontal");
rigidBody.velocity = new Vector2(movement * speed, rigidBody.velocity.y);
if (Input.GetButtonDown("Jump"))
{
rigidBody.AddForce(transform.up * jumpSpeed, ForceMode2D.Impulse);
}
}

Let script modify transform position even if the gameobject is disabled

I am trying to use Main Camera position to make an appear and disappear. For example, if the camera.main.transform.position = (0,2,0); make the object appear otherwise make it disappear.
The object in this case a basic Cube. I started using setActive function but as it turns out once you have setActive as false, Update function on the specific object does not run. I have added the script I was using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class backandforth : MonoBehaviour
{
public float speed = 2.5f;
GameObject targetObject;
// Use this for initialization
void Start()
{
targetObject = GameObject.Find("Cube");
targetObject.SetActive(false);
}
// Update is called once per frame
void Update()
{
//move the cube from (0,0,0)
if (Camera.main.transform.position== new Vector3(0, 2, 0)) {
transform.position = new Vector3(Mathf.PingPong(Time.time * speed, 5), transform.position.y, transform.position.z);
transform.Rotate(0, 0, 5);
}
else
{
targetObject.SetActive(true);
transform.position = new Vector3(Mathf.PingPong(Time.time * speed, 5), transform.position.y, transform.position.z);
transform.Rotate(0, 0, 100);
//gameObject.SetActive(false);
}
}
}
Here is the hierarchy view of the setup to make the GameObject definition clear.
Any suggestion on how do I go about doing this? Thanks!
If I understand correctly the update method should be like this:
void Update()
{
if (Camera.main.transform.position== new Vector3(0, 2, 0)) {
//if the camera.main.transform.position = (0,2,0); make the object appear
targetObject.SetActive(true);
}
else
{
//otherwise make it disappear
targetObject.SetActive(false);
}
}

Enemy movement just on some portion of ground 2D Unity

Can I make my enemy move just on some suspended blocks? I have a script but my enemy fall of them and doesn't stop when is not any block around . I am bound to put blocks higher just to stop his fall?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
private float latestDirectionChangeTime;
private readonly float directionChangeTime = 3f;
private float characterVelocity = 2f;
private Vector2 movementDirection;
private Vector2 movementPerSecond;
void Start()
{
latestDirectionChangeTime = 0f;
calcuateNewMovementVector();
}
void calcuateNewMovementVector()
{
//create a random direction vector with the magnitude of 1, later multiply it with the velocity of the enemy
movementDirection = new Vector2(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f)).normalized;
movementPerSecond = movementDirection * characterVelocity;
}
void Update()
{
//if the changeTime was reached, calculate a new movement vector
if (Time.time - latestDirectionChangeTime > directionChangeTime)
{
latestDirectionChangeTime = Time.time;
calcuateNewMovementVector();
}
//move enemy:
transform.position = new Vector2(transform.position.x + (movementPerSecond.x * Time.deltaTime),
transform.position.y + (movementPerSecond.y * Time.deltaTime));
}
}

How do i set the velocity of a sprite to the opposite direction of the mouse pointer at a certain speed?

/*I am making a 2d game in Unity that works similarly to billiards, but with other aspects. When the player holds down button 0, a line drags away from the ball to show the direction and speed the ball will be hit off in. I don't know how to set that velocity or how to add a force like that.
I've tried setting the velocity directly, then adding fake frictions, but that didn't work too well. I also tried adding a force to the ball, and also making an empty game object that follows the pointer with a point effecter to repel the ball. But I cant seem to get anything to work.
--Also I apologize for the messy code, i'm still kinda new to this
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineDrawer : MonoBehaviour
{
public Transform tr; //this is the transform and rigid body 2d of the
ball
public Rigidbody2D rb;
public LineRenderer line; // the line rendered is on the ball
public float hitForce = 10;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
line.SetColors(Color.black, Color.white);
}
// Update is called once per frame
void FixedUpdate()
{
line.SetPosition(0, tr.position - new Vector3(0, 0, 0));
if (Input.GetMouseButton(0)&&PlayerPrefs.GetInt("Moving")==0)
{
line.SetWidth(.25f, .25f);
line.SetPosition(1, Camera.main.ScreenToWorldPoint(Input.mousePosition));
float len = Vector2.Distance(line.GetPosition(0), line.GetPosition(1)); //this is for determining the power of the hit
}
else
{
line.SetWidth(0, 0); //make the line invisible
}
if (Input.GetMouseButtonUp(0) && (PlayerPrefs.GetInt("Moving")==0))
{
Vector2.Distance(Input.mousePosition, tr.position)*100;
Debug.Log("Up");
rb.velocity = //this is what i cant work out
PlayerPrefs.SetInt("Moving", 1);
}
}
}
//5 lines from the bottom is where i'm setting the velocity.
Just rewrite your script to the following:
using UnityEngine;
public class Ball : MonoBehaviour
{
private LineRenderer line;
private Rigidbody2D rb;
void Start()
{
line = GetComponent<LineRenderer>();
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
line.SetPosition(0, transform.position);
if (Input.GetMouseButton(0))
{
line.startWidth = .05f;
line.endWidth = .05f;
line.SetPosition(1, Camera.main.ScreenToWorldPoint(Input.mousePosition));
}
else
{
line.startWidth = 0;
line.endWidth = 0;
}
if (Input.GetMouseButtonUp(0))
{
Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
direction.Normalize();
rb.AddForce(direction * 3f, ForceMode2D.Impulse);
}
}
}

Categories