- Home /
Sendmessage/GetComponent (read variable only) help
EDIT - Answer helped - created knew unknown problem.
Skip slightly past First answer, under the 3rd body of codes I reply with a new issue in regards to a myTransform conflicting with Ref' to another object (neither are interacting in the script as far as I know - it throws a null error) any help would be great guys.
Ok so I've got something else I want to learn. I'll try my best to explain the situation because I'm getting a bit deeper and deeper... my goal is still to chop down a tree using click moving pathfinding. What I've got so far 1. Hover over, change color, on exit change back. 2. If clicked check player dist, if out of range, leave cutDown false 3. If within range, set cutDown to true 4. GOAL - send a message, or access cutDown in ChopTree to Player to determine if true so I can 1) Disable Movement, 2) Face Tree - I think I'll be fine in regards to LookAt calls once I do get to determine if I am really ready to cut down a tree.
These scripts are in a slightly mangled state at this time since I've been trying so many methods. Not looking for someone to write the script for me, looking for a better job at reading variables from another script. I looked over Sendmessage and Component in the ref - I understand Component and like I said how to change values - I only want to read... I've tried both methods but I can't seem to get the syntax right or find what I need as most examples involve a FP view, or 3rd with direct character control and not pathfinding control... Sorry for the long wall of text but I wanted to explain in detail rather then not.
CharacterAnimation script
enter code hereusing System.Collections;
public class CharacterAnimations : MonoBehaviour {
//THE SCRIPT THAT IS IN THE SAME OBJECT IS CALLED "AIFollow" I do a public attach here.
//Attach to AIFollow to get speed
public AIFollow script;
//Bool for is movving happenin to enable run animation? If stop'd no run.
public bool isMove;
//Keeps track of movement
Transform myTransform;
//Stores the transform at last vector
Vector3 lastPos;
void Start()
{
//ref the script AIFollow at the start
script = GetComponent<AIFollow>();
//declare move at false at start
isMove = false;
//establish a way to track this object
myTransform = transform;
//establish a way to store last vector from object
lastPos = myTransform.position;
}
void Update(){
if ( myTransform.position != lastPos )
isMove = true;
else
isMove = false;
//After checking to see if update was the same as old position, MAKE them the same.
lastPos = myTransform.position;
//If old vector was the same, move will be false and this will be bypassed.
if (Input.GetKey(KeyCode.LeftShift) && isMove != false){
script.speed = 14;
animation.CrossFade ("mRunning");
}else{
script.speed = 5;
}
//if its bypassed and shift is not down, walk
if(script.speed == 5 && isMove != false){
animation.CrossFade("mWalking");
}
//since it was bypassed, and ismove is false, he cannot be moving. Display idle animation.
if (isMove == false){
animation.CrossFade("mIdle");
}
}
//Function to make character get msg and turn toward tree sending it.
void LookAtTree(bool cutDown)
{
Debug.Log("CutDown MSG IN");
}
}
ChopTree script
enter code hereusing UnityEngine;
using System.Collections;
public class ChopTree : MonoBehaviour {
//set tree health
//private int treeHealth = 30;
//Cut tree down
public bool cutDown = false;
//ref Player
public GameObject Player;
//distance to tree?
public float playerDist;
//store orginal color
private Color startcolor;
//display GUI text
private bool showGUI = false;
void Start()
{
//ref
Player = GameObject.Find ("Reiss");
}
void Update()
{
}
//Mouse over event to store color of tree, change red, and then show chop tree
void OnMouseEnter(){
startcolor = renderer.material.color;
renderer.material.color = Color.red;
showGUI = true;
}
//Mouse over event to remove GUI display and return to normal color
void OnMouseExit()
{
renderer.material.color = startcolor;
showGUI = false;
}
//information about the GUI to display and where to display it.
void OnGUI()
{
if (showGUI)
{
//displace text in center screen
GUI.Label (new Rect(Screen.width/2-50,Screen.height/2-50,100,20),"Chop Tree?");
//check if mouse is down and within distance
if(Input.GetMouseButtonDown(0))
{
float playerDist = Vector3.Distance(Player.transform.position, this.transform.position);
CheckDistance();
//Debug.Log(playerDist);
if(playerDist < 13)
{
//if true going to start animations and damage to tree
cutDown = true;
SendMessage("LookAtTree",Player);
Debug.Log(cutDown);
}
}
if (cutDown)
{
}
}
}
//Attempting to use a function call to check distance so update doesn't do it all the time.
public float CheckDistance()
{
float playerDist = Vector3.Distance(Player.transform.position, this.transform.position);
return playerDist;
}
}
Answer by xandermacleod · Jun 20, 2013 at 11:08 PM
Generally I usually find the best way to access variables from a different script is to use the GetComponent way of doing things. Let's say for example you wanted to access the 'cutDown' bool from the ChopTree script. You would first make sure the variable is public (which it already is), and then in the other script you would do the following:
public GameObject exampleObject;
private ChopTree exampleScript;
void Start()
{
exampleScript = exampleObject.GetComponent<ChopTree>();
}
void Update()
{
//now to access the variable you would simply do
exampleScript.cutDown
}
alternatively if you have different scripts that you want to have include the same function name, but you don't know what the script is called you could use what is called an abstract class.
Hope this helps.
p.s. the same can be done with functions, so you could set LookAtTree function to being public, then using that same method, do- exampleScript.LookAtTree(Player);
ins$$anonymous$$d of the Send$$anonymous$$essage currently in place.
So it would look like
public GameObject exampleObject;
private CharacterAnimations exampleScript;
void Start()
{
exampleScript = exampleObject.GetComponent<CharacterAnimations>();
}
void Update()
{
//now to access the variable you would simply do
exampleScript.LookAtFunction(Player);
}
Well I feel like the last post was a step in the right direction - it didn't throw any errors. It messed up a ref using myTransform some how so thats throwing a null ref... and its not displaying "$$anonymous$$SG FRO$$anonymous$$ PLAYER" even though I am 100% sure True is kicking on in ChopTree script.... :|
S$$anonymous$$IP TO HERE - NEW PROBLE$$anonymous$$ EXPLAINED.
Ok so maybe someone can explain this to me.
If I have cutTree at the top, nullref to myTransform... if I move it under myTransform - null ref to game object... NullRef to myTransform...
void Start()
{
cutTree = cutObject.GetComponent<ChopTree>();
//ref the script AIFollow at the start
script = GetComponent<AIFollow>();
//declare move at false at start
is$$anonymous$$ove = false;
//establish a way to track this object
myTransform = transform;
//establish a way to store last vector from object
lastPos = myTransform.position;
//ref cutObject object, and ChopTree script
}
NullRef to cutTree
void Start()
{
//ref the script AIFollow at the start
script = GetComponent<AIFollow>();
//declare move at false at start
is$$anonymous$$ove = false;
//establish a way to track this object
myTransform = transform;
//establish a way to store last vector from object
lastPos = myTransform.position;
//ref cutObject object, and ChopTree script
cutTree = cutObject.GetComponent<ChopTree>();
}
What Unity rule am I making a mess of now? 0.0
Ahh forgot to use inspector. What are the work arounds if I wanted several different types of trees to be able to cut? Would I just have to keep expanding on types in the inspector window?
You've been a massive ball of knowledge so far man.
you could do that, but if you have lots of different tree types it might make more sense to use either an abstract class or what is called an Interface.
They are a bit more complicated. Abstract classes can be thought of as classes that contain 'frameworks' for variables and functions, but don't include the content of those functions. So for example let's say you have a function that you want two different scripts to possess the same name for, but have different stuff inside, then you would use an abstract class. You might be best to check out some of the unity answer stuff on abstract classes and interfaces for that, as t might be a bit much for me to explain.
If it gets a bit too daunting though the multiple inspector stuff is fine. Soz I cant be more help for now.
Your answer
Follow this Question
Related Questions
Move a cube from GUITexture. Is not working. Where is my mistake 0 Answers
Get Component gets the wrong component 0 Answers
acting on other object during collision: SendMessage or GetComponent? 1 Answer
about SendMessage 2 Answers
How would I do SendMessage to a specific component on the same object? 2 Answers