I'm getting the error NullReferenceException: Object reference not set to an instance of an object
ThirdPersonCamera.Update () (at Assets/scripts/ThirdPersonCamera.cs:24)
My Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.SocialPlatforms;
using UnityEngine.UI;
using UnityStandardAssets.Utility;
public class ThirdPersonCamera : MonoBehaviour {
[SerializeField]Vector3 cameraOffset;
[SerializeField]float damping;
Transform cameraLookTarget;
Player localPlayer;
void Awake () {
GameManger.Instance.OnLocalPlayerJoined += HandleOnLocalPlayerJoined;
}
void HandleOnLocalPlayerJoined (Player player) {
localPlayer = player;
cameraLookTarget = localPlayer.transform.Find("cameraLookTarget");
if (cameraLookTarget == null) {
cameraLookTarget = localPlayer.transform;
}
}
// Update is called once per frame
void Update () {
Vector3 targetPosition = cameraLookTarget.position + localPlayer.transform.forward * cameraOffset.z +
localPlayer.transform.up * cameraOffset.y +
localPlayer.transform.right * cameraOffset.x;
transform.position = Vector3.Lerp(transform.position, targetPosition, damping * Time.deltaTime);
}
}
I've tried changing the Script Execution Order, but nothing works. I don't know what's wrong.
Make sure you have a GameObject assigned to the LocalPlayer variable in your script. This object is looking in your hierarchy for something called 'cameraLookTarget' without quotes. Capitalization matters.
I recommend looking for a LocalPlayer object in your Awake() method and if it is null use Debug.Log("No local player assigned") to alert yourself that this is in fact not being assigned.
Related
Got a problem with using the scene manager. Already had a using UnityEngine.SceneManagement still shows the error of both LoadScene and GetActiveScene. I don't have a class such as "SceneManager". Here is the code.
using UnityEngine.SceneManagement;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
bool alive = true;
public float speed = 5f;
public Rigidbody rb;
float horizontalInput;
float horizontalMultiplier = 1.7f;
private void FixedUpdate()
{
if (!alive) return;
Vector3 forwardMove = transform.forward * speed * Time.fixedDeltaTime;
Vector3 horizontalMove = transform.right * horizontalInput * speed * Time.fixedDeltaTime * horizontalMultiplier;
rb.MovePosition(rb.position + forwardMove + horizontalMove);
}
// Update is called once per frame
void Update()
{
horizontalInput = Input.GetAxis("Horizontal");
if (transform.position.y < -5)
{
end();
}
}
public void end ()
{
alive = false;
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
Here is the error I have.
First of all try:
UnityEngine.SceneManagement.SceneManager.LoadScene( "myScene");
There can be 2 troubles:
First -
This happened to me. I had downloaded an asset off the store called Falling Leaves. It included a script called SceneManager. Namespaces should be better utilized for store assets. I'll have to take a look at the code to my own to make sure I'm not breaking someone else's project unintentionally.
Second - if you are wirtting kinda your own lib for unity check that all .dll / projects was imported or if you are writting code in folder that marked with .asmdef this is tool in unity that helps with faster compile and more separeted development (there) and if you are do smth with this asmdef file and checkbox "include unity engine" is not setted as true this is too can be reason so check pls
Same question was answered there https://forum.unity.com/threads/scenemanager-does-not-contain-a-definition-for-loadscene.388892/
I believe you have to be using UnityEngine; before actually using UnityEngine.SceneManagement
here's an example
using UnityEngine; using UnityEngine.SceneManagement;
the problem here is that your using a part or branch or something of EnityEngine before using UnityEngine itself
I'd like to move my player object to click point
with constant velocity so I used MoveTowards() method but it teleports towards click point and doesn't reach the point..If it works properly I'll put walking motion in it. Please check my codes..
And I want to get advice on whether use Update() or FixedUpdate(). FixedUpdate() also doesn't wolks well. It takes mouse events not every time.
here's codes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Collections;
namespace Assets.Scripts
{
public class moveToTarget : MonoBehaviour
{
public GameObject player;
private void Awake()
{
player = GameObject.Find("player");
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 clickPoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, -Camera.main.transform.position.z));
Vector3 pos = player.transform.position;
Vector3 current = pos;
Vector3 desPos = new Vector3(clickPoint.x, pos.y, 0);
//I want to move object horizontally
Debug.Log(clickPoint);
player.transform.position = Vector3.MoveTowards(current, desPos, 100.0f * Time.deltaTime);
}
}
}
}
The Third input of the MoveTowards function is maxDeltaDistance. The bigger it is the faster your object will move. You are using move towards inside an If statement, which might be the cause for not reaching the target.
So I'm making a crap version of flappy bird just for pratice and I want to spawn pipes in increments based on time, so I can then later start removing time to make it prgressively harder.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pipe_Spawner : MonoBehaviour
{
public GameObject pipesPrefab;
// Start is called before the first frame update
void Start()
{
}
public float secsToNext -= Time.deltaTime// public lets you check it running in the inspector
{
// Update is called once per frame
void Update()//every single frame its called
{
secsToNext -= Time.deltaTime; // T.dt is secs since last update
if(secsToNext<=5) {
secsToNext = Random.Range(8.0f, 12.0f);
float Vertical = Random.Range(1.0f, 6.0f);
float Horizontal = Random.Range(-7.0f, 7.0f);
Instantiate(pipesPrefab, new Vector2(Vertical,Horizontal), Quaternion.identity);
}
}
}
}
my errors showing up in unity are:
Assets\pipe_Spawner.cs(13,29): error CS1003: Syntax error, ',' expected
Assets\pipe_Spawner.cs(13,32): error CS1002: ; expected
Assets\pipe_Spawner.cs(14,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration
Assets\pipe_Spawner.cs(27,1): error CS1022: Type or namespace definition, or end-of-file expected
In that order if it matters
right now the coordinates are random purely for testing purposes.
you have to declare the variable secsToNext first before you subtract something from it. i would recommend to spawn a set of pipes at the start and also set the value for secsToNext in the start method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pipe_Spawner : MonoBehaviour
{
public GameObject pipesPrefab;
public float secsToNext;
void Start() //Instantiating the pipes and set the secsToNext at the start
{
secsToNext = Random.Range(8.0f, 12.0f);
float Vertical = Random.Range(1.0f, 6.0f);
float Horizontal = Random.Range(-7.0f, 7.0f);
Instantiate(pipesPrefab, new Vector2(Vertical,Horizontal), Quaternion.identity);
}
void Update()
{
secsToNext -= Time.deltaTime; // T.dt is secs since last update
if(secsToNext <= 5)
{
secsToNext = Random.Range(8.0f, 12.0f);
float Vertical = Random.Range(1.0f, 6.0f);
float Horizontal = Random.Range(-7.0f, 7.0f);
Instantiate(pipesPrefab, new Vector2(Vertical,Horizontal), Quaternion.identity);
}
}
}
This is a reduced version of the player controller I am using now, which still produces the error explained below:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}
I am using the standard assets script and I am trying to have a script teleport the player to different places. When I try and move the player it goes to that position for a frame, then goes right back to its position.
player.transform = new Vector3(1,2,3);
// works as expected, but then next frame, player's
// position is back to where it was before
This problem occurs because Move may not be able to read the up-to-date values for transform.position.
This problem has been reported on the official Unity Issue Tracker here, and a solution was posted there as well:
The problem here is that auto sync transforms is disabled in the physics settings, so characterController.Move() won't necessarily be aware of the new pose as set by the transform unless a FixedUpdate or Physics.Simulate() called happened in-between transform.position and CC.Move().
To fix that, either enable auto sync transforms in the physics settings, or sync manually via Physics.SyncTransforms right before calling Move()
So, you could fix your problem by editing FixedUpdate so that it calls Physics.SyncTransforms before Move, like this:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
Physics.SyncTransforms();
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}
I am currently working on a game prototype, this game would require to
spawn some GameObjects which I call "stars", all good with
instantiating, but when I try to delete them when there are to many
around it does not work, I am trying to put all instantiated
GameObjects in a list and then delete the last object from it when
the new one was instantiated. As you can see from the code, when 3
objects are spawned the script should delete one from the beginning
and spawn a new one in the same time.
Now, the problem is that I don't know what am I missing here, the code does not work and I don't know why. Please help me. Thank you!
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnStar : MonoBehaviour {
public float addedSpeed = -200f;
private GameObject spawned;
private float randomX;
public GameObject starToSpawn;
private List<GameObject> activeGO;
void Start ()
{
activeGO = new List<GameObject> ();
Invoke ("InstantiateStar", 2f);
}
// Update is called once per frame
void FixedUpdate ()
{
GetComponent<Rigidbody>().AddForce( new Vector3( 0f, addedSpeed, 0f));
}
void InstantiateStar ()
{
randomX = Random.Range (-3f, 3f);
GameObject GO;
GO = Instantiate (starToSpawn, new Vector3(randomX, 5f, 0f), transform.rotation) as GameObject;
activeGO.Add (GO);
if ( activeGO[0].transform.position.y < -2f)
{
DeleteActiveGO ();
}
}
void DeleteActiveGO ()
{
Destroy (activeGO [0]);
activeGO.RemoveAt (0);
}
}
I am back with an update. The problem was that I was trying to do 2 thing in one script...short story: To solve the problem I created an empty object in the scene, divided my script in 2 separated scripts, one that makes the spawned object move faster and one that is spawning the object, I put the script that moves the object on to the object that will be spawned and The other script on the empty GameObject that will spawn the "Stars" and it worked like a charm.
Thank you for all your answers!
here are the final scripts:
Spawning script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnStars : MonoBehaviour {
public GameObject[] starsToSpawn;
private List<GameObject> spawnedStars;
private float randomX;
void Start ()
{
spawnedStars = new List<GameObject> ();
InvokeRepeating ("SpawnStar", 0f, 3f);
}
void SpawnStar ()
{
randomX = Random.Range (-3, 3);
GameObject GO;
GO = Instantiate ( starsToSpawn[0], new Vector3 (randomX, 5f, 0f), transform.rotation);
spawnedStars.Add (GO);
if (spawnedStars.Count > 2 )
{
Destroy (spawnedStars [0]);
spawnedStars.RemoveAt (0);
}
}
}
Moving script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveStar : MonoBehaviour {
public float acceleration = -5f;
void FixedUpdate ()
{
GetComponent<Rigidbody>().AddForce( new Vector3( 0f, acceleration,0f));
}
}
Your code Invoke ("InstantiateStar", 2f); only call once.
You can change to InvokeRepeating("InstantiateStar",2f,2f );
The Code GetComponent<Rigidbody>().AddForce( new Vector3( 0f, addedSpeed, 0f)); seem like should attach to the Generate Gameobject.
Also note your delete condition.
good luck.
#Noobie: What you are trying to do is called Object Pooling. Your implementation is rather not correct.
It would be better for you to learn the same and implement.
Read more here: https://unity3d.com/learn/tutorials/topics/scripting/object-pooling