im trying to grab the transform component via t.find and then via the transform component, grab the game object component, and then t.LookAt can work, and look at the player.
this is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class gunner : MonoBehaviour
{
//legacy statements: isShot
//these statements initialize all the main variables used in the project. most of these are for the "ai".
#region variables
[Header("gun stats")]
[Space(10)]
public float damage = 10f;
public float range = 100f;
[Space(10)]
[Header("Camera")]
[Space(10)]
public Camera cam;
[Space(10)]
[Header("AI Variables")]
[Space(10)]
public float shootlength;
public bool aiactive;
public float Speed;
public target self;
public Transform t;
public Rigidbody rb;
public string playername = "Player";
public GameObject PlayerObject;
public Transform PlayerTrans;
[Header("Decor")]
public ParticleSystem ps;
AudioSource audioData;
#endregion
#region gunmanager
private void Start()
{
GameObject PlayerObject = GameObject.Find(playername);
Transform PlayerTrans = PlayerObject.GetComponent<Transform>();
}
void Update()
{
if(aiactive && PlayerTrans != null)
{
Debug.Log("player trans found!");
}
if(aiactive && PlayerObject != null)
{
Debug.Log("player gameObject found!");
}
if(aiactive && PlayerTrans != null && PlayerObject != null)
{
Debug.Log("test passed!");
}
audioData = GetComponent<AudioSource>();
if (Input.GetButtonDown("Fire1") && !aiactive)
{
audioData.Play(0);
Shoot();
}
if(aiactive)
{
StartCoroutine(aiman());
}
}
public void Shoot()
{
ps.Play();
RaycastHit hit;
if(Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, range))
{
Debug.Log("Hit:" + hit.transform.name);
target targ = hit.transform.GetComponent<target>();
if (targ != null)
{
if(!aiactive)
{
self.hp += 50;
}
targ.TakeDamage(damage);
}
}
}
public void aiActivity()
{
if(self.hp >= 0)
{
t.LookAt(PlayerTrans);
rb.AddRelativeForce(Vector3.forward * Speed * Time.deltaTime);
RaycastHit hitplayer;
if(Physics.Raycast(cam.transform.position, cam.transform.forward, out hitplayer, shootlength))
{
if(hitplayer.transform == PlayerObject)
{
Shoot();
}
}
}
else
{
rb.useGravity = true;
aiactive = false;
}
}
IEnumerator aiman()
{
yield return new WaitForSeconds(1f);
aiActivity();
}
#endregion
}
so no compiler errors, but it cannot find the player and float towards it, and therefore, I cannot get this to work.
Here are a few issues with the updated snippet, not sure if they will fix all of the errors you are getting.
You are re-using a variable name t. I would also refrain from naming any global variables very short random letters as it can get confusing. What is this a Transform of? If it is the transform of a player, possibly name it PlayerTransfom.
As I mentioned you are re-using a variable name which is not allowed especially with different types as well as re-initilization. It is fine to re-assign a variable such that it is updated, manipulating, changing, etc. the value, but re-declaring the value is not allowed in c# and I do not believe allowed in any other language (at least that I know of).
To be specific, the line target t = hit.transform.GetComponent<target>(); is delcaring t as the script component type target, but you have already declared a Transform named t above it as public Transform t;.
Another issue is you are attempting to assign a variable using a non-static method in a global setting. The line specifically is public Transform player = Transform.Find(playername);. You are not able to set the transform like this outside of a method as the Find method is not static. Change it to be.
public Transform player;
private void Start()
{
player = Transform.Find(playername);
}
The second error is because of the same reason, but due to this line public GameObject PlayerObject = player.GetComponent<GameObject>();. Again, GetComponent is a nonstatic method so can not be called in a global setting. The other issue is GameObject is not a component, it is a type. GameObjects have components so you can not get the component of itself as it does not exist. You are already using Transform.Find which finds a transform, I would recommend just finding the GameObject, storing that reference then get the Transform from the gameObject. You do not really need to store the transform as its own reference if you have the GameObject reference though.
public Transform player;
public GameObject PlayerObject;
private void Start()
{
PlayerObject = GameObject.Find(playername);
player = PlayerObject.transform;
}
The final error being outputted is specifying that you are using LookAt incorrectly. You need to pass in a type of Transform, but you are passing in a type of GameObject. Change it to...
t.LookAt(player);
Most of these issues are rather trivial and straightforward. I would follow along with a tutorial or read through the docs to get a better understanding of C#/Unity/Programming. Being a beginner is fine, but StackOverflow should not just be used as debugging help when the errors are right there. I do not know if the 4 recommendations I mentioned will fully fix your program as I did not run it. There could be more issues than what I had mentioned, but following the errors should tell you what is wrong and why it is wrong. It is printing the line number, file, and reason for why it is breaking.
Related
I am recently new to c# and I need some help.
Essentially I have two scripts, one for spawning objects and one for moving an object along a path. I need a way to combine these two mechanics so that when a new object is instantiated it automatically joins the path and follows it.
The path is made using iTween.
![The objects the scripts are attached to] (https://i.stack.imgur.com/QPQn2.png)
I've tried changing the variable m_PlayerObj to the cube prefab and I've tried adding the Path script to the instantiation script but nothing seems to work.
The scripts attached do nkt include these attempts I made as I wanted to make the code very clear.
Spawner script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnerScript : MonoBehaviour
{
public GameObject cubeprefab;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(cubeprefab, transform.position, Quaternion.identity);
}
}
}
Path script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Path : MonoBehaviour
{
public GameObject m_PlayerObj;
public Transform[] positionPoint;
[Range(0, 1)]
public float value;
// Start is called before the first frame update
void Start()
{
Debug.Log(iTween.PathLength(positionPoint));
}
float tempTime;
// Update is called once per frame
void Update()
{
if (value < 1)
{
value += Time.deltaTime / 10;
}
iTween.PutOnPath(m_PlayerObj, positionPoint, value);
}
private void OnDrawGizmos()
{
iTween.DrawPath(positionPoint,Color.green);
}
}
As stated above, any help would be greatly appreciated as I am really stuck on this conceot and since I am new to Unity I really can’t see a way around it // how to fix it.
Instead of only storing the player object in the Path script, store a collection of objects. That way, the path can keep track of more than one object.
//public GameObject m_PlayerObj; // Get rid of this
public List<GameObject> followers; // Add this
Then, in your Update loop, you can loop through all of them.
void Update()
{
for (var i = 0; i < followers.Length; ++i)
{
if (value < 1)
{
value += Time.deltaTime / 10;
}
iTween.PutOnPath(m_PlayerObj, positionPoint, value);
}
}
Of course, now, you need to make sure you pass your cube instance to the Path GameObject when you spawn it, so the path knows about the cube follower. That means your spawner also needs to know about the path.
public class SpawnerScript : MonoBehaviour
{
public GameObject cubeprefab;
public Path path; // Need to populate this in the Editor, or fetch it during Awake()
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
var cubeInst = Instantiate(cubeprefab, transform.position, Quaternion.identity);
path.followers.Add(cubeInst);
}
}
}
Now a new problem is going to be that each object is going to be at the same position on the path, because the path only stores one value - a better term might be progress. So if they're all the same, like the cube, you won't be able to tell because they'd overlap.
So you have to decide what you want to do instead. Evenly space them? You could do that with some math. Or have them all start from the beginning and keep track of their progress separately? Then you'd need to store progress for each of them. A better place to do that is probably on the cube object, which means you need to add a new script to your cube prefab:
public class PathFollower : MonoBehaviour
{
[Range(0, 1)]
public float pathProgress;
}
And, you need to start referring to the prefab by this script, instead of just GameObject:
public class SpawnerScript : MonoBehaviour
{
public PathFollower pathFollower;
public Path path; // Need to populate this in the Editor, or fetch it during Awake()
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
var followerInst = Instantiate(pathFollower, transform.position, Quaternion.identity);
path.followers.Add(followerInst);
}
}
}
public class Path : MonoBehaviour
{
//public GameObject m_PlayerObj; // Get rid of this
public List<PathFollower> followers; // Add this
//...
Finally, you need to make sure to use the individual progress for each path follower, rather than a single progress value like your old Path script did:
for (var i = 0; i < followers.Count; ++i)
{
if (followers[i].pathProgress < 1)
{
followers[i].pathProgress += Time.deltaTime / 10;
}
iTween.PutOnPath(followers[i].gameObject, positionPoint, followers[i].pathProgress);
}
Putting it all together (separate files of course, with their own includes!):
public class SpawnerScript : MonoBehaviour
{
public PathFollower pathFollower;
public Path path; // Need to populate this in the Editor, or fetch it during Awake()
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
var followerInst = Instantiate(pathFollower, transform.position, Quaternion.identity);
path.followers.Add(followerInst);
}
}
}
public class Path : MonoBehaviour
{
//public GameObject m_PlayerObj; // Get rid of this
public List<PathFollower> followers; // Add this
public Transform[] positionPoint;
//[Range(0, 1)]
//public float value; // Don't need this anymore either
// Start is called before the first frame update
void Start()
{
Debug.Log(iTween.PathLength(positionPoint));
}
// Update is called once per frame
void Update()
{
for (var i = 0; i < followers.Count; ++i)
{
if (followers[i].pathProgress < 1)
{
followers[i].pathProgress += Time.deltaTime / 10;
}
iTween.PutOnPath(followers[i].gameObject, positionPoint, followers[i].pathProgress);
}
}
private void OnDrawGizmos()
{
iTween.DrawPath(positionPoint,Color.green);
}
}
public class PathFollower : MonoBehaviour
{
[Range(0, 1)]
public float pathProgress;
}
Just picked up Unity about a week ago, I have really been struggling to fix this problem and referencing overall, I'm well aware that I need to read and watch more tutorials, I just want to get this fixed so I can continue working on my game.
An object reference is required for the non-static field, method, or property PlayerMovement.activeMoveSpeed
The first problem was referencing the other Game Object and script, I not sure if its completely fixed now but
at least that not the error that its giving me anymore, I've tried doing what this link says
https://answers.unity.com/questions/1119537/help-how-do-i-referenceaccess-another-script-in-un.html
but as you might see it hasn't worked out, every single time I get the compile errors fixed the script doesn't work because the object reference is not set to an instance of an object, any help would be extremely appreciated (the script I'm trying to reference will be at the end)
Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShieldAttack : MonoBehaviour
{
public GameObject shield;
private Vector3 mousePos;
private Camera mainCam;
public bool isDashing;
private Rigidbody2D rb;
GameObject Player;
PlayerMovement playerMovement;
Shooting shooting;
// Start is called before the first frame update
void Start()
{
GameObject.FindGameObjectWithTag("EnemyMelee");
GameObject.FindGameObjectWithTag("Enemy2");
mainCam = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
mousePos = mainCam.ScreenToWorldPoint(Input.mousePosition);
Vector3 rotation = mousePos - transform.position;
float rotZ = Mathf.Atan2(rotation.y, rotation.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, rotZ);
if (Input.GetKeyDown(KeyCode.Space) && playerMovement.dashCoolCounter <= 0 && playerMovement.dashCounter <= 0)
{
isDashing = true;
Instantiate(shield, shooting.bulletTransform.position, Quaternion.identity);
if (PlayerMovement.activeMoveSpeed == 5)
{
DestroyShield();
isDashing = false;
}
}
}
void DestroyShield()
{
Destroy(gameObject);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed;
public Rigidbody2D rb2d;
private Vector2 moveInput;
public float activeMoveSpeed;
public float dashSpeed;
public float dashLength = 0.5f, dashCooldown = 1f;
public float dashCounter;
public float dashCoolCounter;
[SerializeField] private TrailRenderer tr;
//Start is called before the first frame update
void Start()
{
activeMoveSpeed = moveSpeed;
}
//Update is called once per frame
void Update()
{
if(dashCounter > 0)
{
tr.emitting = true;
}
if(dashCounter < 0)
{
tr.emitting = false;
}
moveInput.x = Input.GetAxisRaw("Horizontal");
moveInput.y = Input.GetAxisRaw("Vertical");
moveInput.Normalize();
rb2d.velocity = moveInput * activeMoveSpeed;
if (Input.GetKeyDown(KeyCode.Space))
{
if (dashCoolCounter <=0 && dashCounter <=0)
{
activeMoveSpeed = dashSpeed;
dashCounter = dashLength;
}
}
if (dashCounter > 0)
{
dashCounter -= Time.deltaTime;
if (dashCounter <= 0)
{
activeMoveSpeed = moveSpeed;
dashCoolCounter = dashCooldown;
}
}
if (dashCoolCounter > 0)
{
dashCoolCounter -= Time.deltaTime;
}
}
}
You are using class name PlayerMovement.activeMoveSpeed instead of object name playerMovement.activeMoveSpeed in this part of code:
if (PlayerMovement.activeMoveSpeed == 5)
{
DestroyShield();
isDashing = false;
}
Also I cannot see playerMovement variable initialization in the ShieldAttack script. You need to mark it with the [SerializeField] attribute or make it public to be able to assign it in the inspector. Or initialize it in your Start() method along with the other fields.
When you create a variable, you do <type> <name>, where <type> is the kind of thing you want to create and <name> is how you want to reference the instance you created.
We as programmers are generally lazy, so if we wanted to create a pineapple we would create an instance of the Pineapple class. What do we call it? Typically just pineapple, and then you wind up with code like
Pineapple pineapple;
The first term means you're wanting to create a Pineapple, and the second term means you're going to refer to that instance as pineapple. Note the capitalization differences there.
The issue with your code is that you've created an instance of PlayerMovement:
PlayerMovement playerMovement;
but when you're trying to use the instance in your code, you are using the class name PlayerMovement and not the instance name playerMovement. Again, note the capitalization difference.
The particular line that you've got:
if (PlayerMovement.activeMoveSpeed == 5)
should instead be:
if (playerMovement.activeMoveSpeed == 5)
to refer to the instance and not the class.
It is possible to have things that are common to all instances of a class. Those are static items and you would access them by referencing the class name instead of the instance name.
The error message you got:
An object reference is required for the non-static field, method, or property PlayerMovement.activeMoveSpeed
was telling you that you were trying to access a part of the class, but it wasn't static, so you needed to reference the object (instance).
and thank you for looking at this in advance.
I have yet another problem that i need to solve and it goes like this:
I have a list of objects that i select with a raycast, and i would like to teleport them to a specific location in the scene. Like for example i have selected a cube and a sphere and they are added to my list called playersTagged.
How can i get the objects in my list to that specific location when OnCollisionEnter with my player that has the tag "Tagger"?
My code looks like this:
PlayerTagged Class
using System.Collections.Generic;
using UnityEngine;
public class PlayerTagged : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public Camera fpsCam;
public List<GameObject> playersTagged;
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null && target.isHit == false)
{
target.takeDamage(damage);
if(hit.collider.tag == "Taggable")
playersTagged.Add(hit.collider.gameObject);
target.isHit = true;
}
}
}
}
Teleport class:
using UnityEngine;
public class Teleport : MonoBehaviour
{
public Transform teleportTarget;
public PlayerTagged player;
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Tagger")
{
Debug.Log("You hit the can");
}
}
}
You need to have the PlayerTagged reference in your Teleport component. If both objects will always exist in your scene, only create a public field in your Teleport and drag and drop your PlayerTagged ref, otherwise you will need to fill this ref by code using some "find" approach, for example, GameObject.FindObjectWithTag().
You can also make an event that trigger when the object that entered the OnTriggerEnter is valid (I mean, when your tag condition pass) and then make sure that PlayerTagged is being registered as listener to this event.
First one is easier to setup, but if you plan to make unique things with this OnTriggerEnter as playing sounds, changing data or something like that, the second one is a better approach.
EDIT: I'll try to insert some code, let me know if you still having problems on getting the idea
"If both objects will always exist in your scene..."
using UnityEngine;
public class Teleport : MonoBehaviour
{
public Transform teleportTarget;
public PlayerTagged player; // I didn't saw that you already have an ref here, my bad, so you only need to access the fields
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Tagger")
{
Debug.Log("You hit the can");
var list = player.playersTagged; // this is how you will access your list
// Do some stuff with your list
}
}
}
Ignore the rest, it will only complicate things
EDIT 2: Making the teleport happen in player, and teleport every object
using System.Collections.Generic;
using UnityEngine;
public class PlayerTagged : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public Camera fpsCam;
public List<GameObject> playersTagged;
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
// Option 1:
private void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "Teleport Tag")
{
var teleport = col.gameObject.GetComponent<Teleport>();
TeleportObjectsTo(teleport.teleportTarget.position);
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null && target.isHit == false)
{
target.takeDamage(damage);
if(hit.collider.tag == "Taggable")
playersTagged.Add(hit.collider.gameObject);
target.isHit = true;
}
}
}
public void TeleportObjectsTo(Vector3 targetPosition)
{
foreach(taggedObjects in playersTagged)
{
taggedObjects.transform.position = targetPosition;
}
}
}
You can also make the teleport happen on teleport script:
using UnityEngine;
public class Teleport : MonoBehaviour
{
public Transform teleportTarget;
public PlayerTagged player; // I didn't saw that you already have an ref here, my bad, so you only need to access the fields
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Tagger")
{
Debug.Log("You hit the can");
// Option 2:
player.TeleportObjectsTo(teleportTarget);
// Option 3: Or you can iterate here instead of make use of the API
foreach(var taggedObjects in player.playersTagged)
{
taggedObjects.transform.position = targetPosition;
}
}
}
}
Chose one option, and delete/comment others
--N
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
For some reason when I'm in the normal view in-game I am able to link the scripts that I need to call in order to make an animation like so
however, whenever I start the game it automatically removes them from the slots, and it doesn't work
I am completely clueless as to why this may be happening and unity keep giving me errors that say that I'm not setting an instance to my script I really have no clue why this may be happening.
I have 3 scripts that I'm working with that is giving me the problem
one is the main script for the enemy vision (I am referencing the other scripts in this one)
the second is the enemy animation script which makes him go from idle to attack and the third is an animation for the gun model since I had to make it follow the hands of the enemy
scripts attached bellow
1st script(enemyAI):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAi : MonoBehaviour
{
public bool detected;
GameObject target;
public Transform enemy;
public GameObject Bullet;
public Transform shootPoint;
public float shootSpeed = 10f;
public float timeToShoot = 1f;
public EnemyAni Animation;
public GunAni GunAnimation;
void Start()
{
Animation = GetComponent<EnemyAni>();
GunAnimation = GetComponent<GunAni>();
}
public void Update()
{
//makes the enemy rotate on one axis
Vector3 lookDir = target.transform.position - transform.position;
lookDir.y = 0f;
//makes enemy look at the players position
if (detected)
{
enemy.LookAt(target.transform.position, Vector3.up);
enemy.rotation = Quaternion.LookRotation(lookDir, Vector3.up);
}
if (detected == true)
{
Animation.LookPlayer = true;
GunAnimation.ShootPlayer = true;
}
if (detected == false)
{
Animation.LookPlayer = false;
GunAnimation.ShootPlayer = false;
}
}
//detects the player
void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
detected = true;
target = other.gameObject;
}
}
void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
detected = false;
}
}
}
2nd Script (EnemyAnimation):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAni : MonoBehaviour
{
public Animator animator;
public bool LookPlayer;
public void Start()
{
animator = GetComponent<Animator>();
}
public void Update()
{
if (LookPlayer == true)
{
animator.SetBool("IsShootingStill", true);
}
else
{
animator.SetBool("IsShootingStill", false);
}
}
}
3rd script (GunAnimation):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunAni : MonoBehaviour
{
public Animator animator;
public bool ShootPlayer;
public void Start()
{
animator = GetComponent<Animator>();
}
public void Update()
{
if (ShootPlayer == true)
{
animator.SetBool("IsShooting", true);
}
else
{
animator.SetBool("IsShooting", false);
}
}
}
Your code:
void Start()
{
Animation = GetComponent<EnemyAni>();
GunAnimation = GetComponent<GunAni>();
}
Searches the GameObject that holds the EnemyAI script for EnemyAni and GunAni. If the GameObject doesn't have those it will return null.
Sounds like you want to remove that code.
Note that if the scripts exist on a child of that GameObject you will need to use GetComponentInChildren
There are some things to review, good practices:
GameObject target is private for C#, but it is better to put private before.
variable names like Bullet Animation GunAnimation should always begin with lowercase, because they might be confused with a Class Name (search in internet for CamelCase and PascalCase).
Name should be clear. EnemyAni Animation is not clear enough, because Animation maybe any animation (player, enemy, cube, car, etc.).
It is better enemyAnimation to be clear, as you did with GunAnimation (only just with lower case at beginning)
As slaw said, the Animation must be in the GO attached.
about last item
Let's say you have an empty GO (GameObject) called GameObject1 and you attach EnemyAi script to it.
In Runtime (when game mode begins), it will try to find Animation = GetComponent<EnemyAni>();, but it won't find it
Why?
Because GetComponent<> searches for the Component(Class) that is in the <> (in this case EnemyAni) in its GO (in this case, GameObject1), but the unique script attached to GameObject1 is EnemyAI.
So, you have 3 options:
Attach EnemyAni to GameObject1
Create another GO (for example, GameObjectEnemyAni), attach the script EnemyAni and drag and drop GameObjectEnemyAni to GameObject1 and delete Animation = GetComponent<EnemyAni>(); in Start
Keep in mind: if you leave that line of code, instead of getting the script EnemyAni from GameObjectEnemyAni, it will run the code Animation = GetComponent<EnemyAni>(); in Start, and obviously, it won't find it
Create events. It's a really good practice for avoiding code tight coupling, but that is more advanced stuff.
So I've got two scripts, one is called EndCollider.cs it's somewhere on the map,
It have one OnTriggerEnter function which set a boolean to true.
using UnityEngine;
using System.Collections;
public class EndCollider : MonoBehaviour {
public bool isShow = false;
void OnTriggerEnter ()
{
isShow = true;
}
}
the other script is SlowDownRun.cs, it's on a monster object, in this script I'm trying to detect if the boolean from another script is true or not, if it is then move the monster.
using UnityEngine;
using System.Collections;
public class SlowDownRun : MonoBehaviour {
GameObject TrollScript;
EndCollider MonsterShow;
// Use this for initialization
void Start ()
{
TrollScript = GameObject.Find("Troll");
MonsterShow = TrollScript.GetComponent<EndCollider>();
}
void Update()
{
if (MonsterShow.isShow == true)
{
float movementSpeed = 10f;
transform.position += transform.forward * Time.deltaTime * movementSpeed;
}
}
}
Now the code doesn't work, the code where move the monster works if I take them out the IF statement. I also keep getting this error NullReferenceException: Object reference not set to an instance of an object on the line if (MonsterShow.isShow == true)
Please help I'm a beginner to Unity and this problem stuck on me for so many hours now, I've done a lot Google searches and modified my code again and again but just can't solve this problem, I feel anxious and just don't know what to do.
Your find troll call in the Start() method is not finding the troll or not finding the EndCollider component on it, resulting in it being null. And since you only search once at startup it will always be null.
This is probably because your troll is not yet created at the start of the scene.
If your intent is actually to make the monster appear when the player hit the collider, you should look at Prefab Instantiation.
http://docs.unity3d.com/Manual/InstantiatingPrefabs.html
So in your OnTriggerEnter, you can simply instantiate a brand new monster:
public class EndCollider : MonoBehaviour {
public GameObject MonsterPrefab;
void OnTriggerEnter ()
{
Instantiate(MonsterPrefab);
}
}
One better way of communicating data between two scenes might be using PlayerPrefs:
//EndCollider.cs
public bool isShown
{
get { return PlayerPrefs.GetInt("IS_SHOWN")==1? true:false; }
set { PlayerPrefs.SetInt("IS_SHOWN", Convert.ToInt32(value));}
}
//SlowDownRun.cs
if(PlayerPrefs.GetInt("IS_SHOWN")==1) // isShown = true
{
...
}
Make masterShow endcollider public
clean your start method.
Just drag and drop the troll object from hierarchy to your script.
public class SlowDownRun : MonoBehaviour {
public EndCollider MonsterShow;
// Use this for initialization
void Start ()
{
}
void Update()
{
if (MonsterShow.isShow == true)
{
float movementSpeed = 10f;
transform.position += transform.forward * Time.deltaTime * movementSpeed;
}
}
}