I am trying to make a game in Unity and I am stuck in a part where I am trying to move a platform from Point A to Point B.
The error I get is:
NullReferenceException: Object reference not set to an instance of an object
MovingPlatform.Update () (at Assets/Scripts/MovingPlatform.cs:30)
The Source Code is:
public class MovingPlatform : MonoBehaviour
{
[SerializeField]
private Transform pointA, pointB;
private float speed = 1.0f;
private Transform target;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (transform.position == pointA.position)
{
target = pointB;
}
else if (transform.position == pointB.position)
{
target = pointA;
}
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
}
What should I do?
Because the platform is not moving at all.
The error tells you whats wrong. In line 30 of your script you have a reference somewhere which is null (hence NullReferenceException) and you try to do something with this (e.g. accessing attributes). I guess its target.position from
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
when your if-statements dont trigger. You should add target = pointB; in Start()
to have target properly initialized (i assume you want start out moving to pointB).
Related
Here is my character controller code.
public float speed;
float Velocity;
public float jump;
void Update ()
{
Velocity = 0;
if (Input.GetKey (KeyCode.LeftArrow) || Input.GetKey (KeyCode.A))
{
Velocity = -speed;
}
if (Input.GetKey (KeyCode.RightArrow) || Input.GetKey (KeyCode.D))
{
Velocity = speed;
}
if (Input.GetKey (KeyCode.UpArrow) || Input.GetKey("space") || Input.GetKey (KeyCode.W))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (GetComponent<Rigidbody2D> ().velocity.x,
jump);
}
GetComponent<Rigidbody2D> ().velocity = new Vector2 (moveVelocity, GetComponent<Rigidbody2D>
().velocity.y);
}
}
This is a very simple movement code
here is my cam follow code i got from Brackeys
I am having an infinte jump problem with the code and i do not know what to do to fix it
I do not know the correct syntax yet to stop it.
I am using Unity 2019.4.2f1 and VScode 2020.
Im not sure if adding what versions I use will help
but I am always getting compiler errors saying that stuff does not exist in the current context but i do not know anything else that does exist in the current context that will work.
void Update()
{
transform.position = playerPos.position + offset;
}
To fix infinite jump, use Input.GetKeyDown(KeyCode.UpArrow) instead of Input.GetKey(KeyCode.UpArrow). The GetKey function is for checking when a key is held down. the GetKeyDown function is for getting the first time the key is pressed.
(This is 2D project)
My character need to run left and right and jump on ground. It is my first experience with Unity and it latest available version of it, I manage to make my Character run left and right and flip when it is change direction, but it does not jump at all.
For the Character I am currently using 2 Box Collider 2Ds and Rigidbody 2D. Character has mass equal 1.
For the Ground I am currently using 2 Box Collider 2Ds. Ground is single sprite which is cover bottom part of screen.
Below is the code for jumping and grounded I am currently trying to use.
'''
{
public float maxSpeed = 10f;
public float jumpVelocity = 10f;
private bool isGrounded;
private float move = 0f;
private Rigidbody2D rb2d; //Store a reference to the Rigidbody2D component required to use 2D Physics.
private SpriteRenderer sprt_render;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
isGrounded = true;
}
// Update is called once per frame
void Update()
{
GetInput();
}
private void GetInput()
{
move = Input.GetAxis("Horizontal");
if (transform.position.x > -6.2 && transform.position.x < 5.7)
{
rb2d.velocity = new Vector2(move * maxSpeed, rb2d.velocity.y);
}
else
{
rb2d.velocity = new Vector2(move * maxSpeed * -1, rb2d.velocity.y);
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
Debug.Log("Jump");
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpVelocity);
isGrounded = false;
//rb2d.AddForce(Vector2.up * jumpVelocity, ForceMode2D.Impulse);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
}
'''
As you can see I try to use two different approach in connection with jump realisation using Velocity and using AddForce result is totally the same it is not jumping even first time. I check thought breakpoint it definitely go trough jumping code but nothing happened.
I have came across similar problem which few people already posted on the forum. I checked the exisiting posts but still not couldn't rectify the issue. I have cube in my program which hits the floor when program starts. However, I found that onCollisionEnter is not being called when cube hits the floor. Rigidbody is attached to the cube. Could anyone guide me where am I making mistake?
Code of cube is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cube : MonoBehaviour
{
public float speed = 3.5f;
public float jumpingforce = 10f;
private bool canjump = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetKey("right"))
{
transform.position += Vector3.right * speed * Time.deltaTime;
}
if(Input.GetKey("left"))
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
if(Input.GetKeyDown("space"))
{
GetComponent<Rigidbody>().AddForce(0,jumpingforce,0);
}
}
void onCollisionEnter(Collision collision)
{
Debug.Log("checking collision....");
}
}
First of all OnCollisionEnter needs to start (as btw any method and class name should in c#) with a capital O .. otherwise Unity will not recognize it and never call it. Unity calls these methods (like also Awake, Start, Update) as "Messages". If they do not exactly match the name they are never found and never called.
Some more things:
Do not call GetComponent repeatedly. It is quite expensive! Rather store the reference once and re-use it.
Then whenever a Rigidbody is involved you should not update it's transformations using the Transform component! This breaks the Physics! Rather use Rigidbody.MovePosition within FixedUpdate
Small Sidenote: Remove any empty Unity message method like Start, Awake, Update. Even if they are empty they are called by Unity as message only causing unnecessary overhead.
So you should change your code to something like
public class cube : MonoBehaviour
{
public float speed = 3.5f;
public float jumpingforce = 10f;
private bool canjump = false;
// you can also already reference this via the Inspector
// then it skips the GetComponnet call
[SerializeField] privte Rigidbody rigidbody;
private void Awake()
{
if(!rigidbody) rigidbody = GetComponent<Rigidbody>()
}
private void FixedUpdate()
{
// Getting this input in FixedUpdate is ok since it is a continues call
if(Input.GetKey("right"))
{
rigidbdy.MovePosition(rigidbody.position + Vector3.right * speed * Time.deltaTime);
}
if(Input.GetKey("left"))
{
rigidbdy.MovePosition(rigidbody.position + Vector3.left * speed * Time.deltaTime);
}
}
private void Update()
{
// this one-time input event has to be checked in Update / frame-based
// since it is true only for one frame and FixedUpdate might not be called during that frame
if(Input.GetKeyDown("space"))
{
// also it's ok calling this in Update since it is a one-time event
// and unlikely to happen twice until FixedUpdate is called again
rigidbody.AddForce(0,jumpingforce,0);
}
}
private void OnCollisionEnter(Collision collision)
{
Debug.Log("checking collision....");
}
}
I almost created game but there is one thing which is hard for me. I want to move player to target and some more.
The red dot is the goal, but I want to move the player to the goal and a little further.
P.S
If the player goes to the right then I want him to reach the goal and a little further to the right
same to the left, top, bottom
Look Attachment: https://imgur.com/a/RF0xIQq
Red dot is a target but i want player move to target and else more on the facing side (green dot)
i tried something like move forward but i dont have any idea.
void Start()
{
}
void Update()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
transform.position = Vector2.MoveTowards(transform.position, target.position, (speed * Time.deltaTime));
}
//Mob have "Player" TAG (Player is not a player) |Targeting is fine|
You could add an offset value
// ajdust this in the inspector
public float offset = 0.1f;
and than add it to the position in the direction from the player to the target. As Foggzie mentioned this might not be a copy-past-able code yet since there might occure some hickups. To atleast prevent that the player turn around after overshooting the target and move back and forth you could use a setter method to get the direction only once:
public float offset;
public float threshold = 0.0001f;
public float speed;
private GameObject target;
private Vector3 direction;
private Vector3 targetPosition;
public void SetTarget(GameObject newTarget)
{
target = newTarget;
// adding the offset in that direction
targetPosition = target.transform.position + direction * offset;
// direction from the player to the target
direction = (target.transform.position - transform.position).normalized;
}
private void Update()
{
if (!target) return;
// make Player overshoot the target by offset
transform.position = Vector2.MoveTowards(transform.position, targetPosition, (speed * Time.deltaTime));
// stop if target is reached
if (Vector3.Distance(transform.position, targetPosition) <= threshold)
{
target = null;
}
}
I don't know when and how you change the target so currently it doesn't limit the player movement to only X and Y like in your pictures ... but you would than do e.g.
// Note that 'transform' is a built-in property of 'GameObject' and you shouldn't use `GetComponent` for it
SetTarget(GameObject.FindGameObjectWithTag("Player").transform);
I've created a movement script that checks to see if an object is grounded, and if so, moves the object based on user input. When I attach it to an object I create in Unity, it works. When I attach it to an object I created in Blender and then imported, nothing. No errors, the object just fails to respond. I can't figure out what is causing the imported object to not respond to input. Both objects have a rigidbody and a collider.
This is the code for movement:
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public float speed = 10f;
public float rotationSpeed = 100f;
private float distToGround;
private Collider collider;
void Start() {
collider = GetComponent<Collider>();
distToGround = collider.bounds.extents.y;
}
void Update() {
MovePlayer();
}
void MovePlayer() {
float translation = Input.GetAxis("Vertical");
float rotation = Input.GetAxis("Horizontal");
if (translation != null && rotation != null) {
if (IsGrounded()) {
transform.Translate(0, 0, translation * speed * Time.deltaTime);
transform.Rotate(0, rotation * rotationSpeed * Time.deltaTime, 0);
}
}
}
bool IsGrounded() {
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
}
}
I've made a video demonstrating this: https://www.youtube.com/watch?v=qatBF5Ov3Zo&feature=youtu.be
This is a complication caused by Blender left handed axis vs Unity's right handed axis. When I exported a rotated object from Blender, the script works on the object as expected. The solution is to make sure that the object you are exporting is facing the Z axis instead of the native Y axis.