Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Kristov · Dec 02, 2010 at 04:41 AM · functionreferencevaluesendmessagecall

My SendMessage is problematic [SOLVED]

Hi all,

I have a script attached to my enemy object (at the moment it's nothing but a cube, so no parent/child issues), which, among other things, calls this function when it dies:

var levelController : Scoreboard; // was var levelController : GameObject; var scoreWorth = 5;

function YouBeDead() { levelController.AddScore(scoreWorth); // was levelController.SendMessage("AddScore", scoreWorth); Instantiate(explosion, transform.position, Random.rotation); Destroy(gameObject); }

(levelController is a GameObject var, and scoreWorth is an int var) My issue is with the levelController line. It sends a message to my Level Controller script, telling it to add x amount of points onto my player's score:

var totalScore : int;

function AddScore(scoreWorth : int) { totalScore += scoreWorth; print (totalScore); }

function OnGUI () { GUI.Label (Rect (0,0,100,50), "Score: " + totalScore); }

The strange part is, it calls the function fine, but it doesn't send the value of scoreWorth. As a test, I put the line print(totalScore); in the AddScore function, and every time I kill an enemy it does print, but it prints 0, so obviously the value isn't travelling with the message.

As always, it's probably something exceedingly simple, but I'm just not seeing it, and am starting to get cranky with it :P

Thanks for your help!

Kristof

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image duck ♦♦ · Dec 02, 2010 at 07:42 AM 1
Share

(p.s. it's "Javascript", not "Java" - they are very different things! - ftfy)

avatar image Kristov · Dec 02, 2010 at 08:22 AM 0
Share

Whoops! I should've known that, guess I just wasn't thinking :P

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by duck · Dec 02, 2010 at 07:41 AM

Have you defined "scoreWorth" as a var in your levelController script? if so, this class-wide definition may be conflicting with the "local" definition that you are trying to set up in the function's parameters. The correct way to do this is to not have a var declared with the same name as your function parameter names.

However, since you already have a variable as a reference to your levelController gameobject, you could go one step further and make that a reference to the script on that gameobject by changing the variable's type to the name of the script. Eg, instead of:

var levelController : GameObject;

You could have:

var levelController : LevelController;

(Assuming your script is named with an initial captial, which is the convention in Unity dev)

This means your variable is now set to receive an object whose type is "LevelController" - the type that you created when you made a script with that exact name.

Once you have this set up, if you drag your levelController gameobject into that slot, the reference will now be to the script instance on that object, rather than the object itself. This means you no longer have to use "SendMessage" to transmit messages, and can instead call the function directly, for example, instead of:

levelController.SendMessage ("AddScore", scoreWorth);

You can have:

levelController.AddScore(scoreWorth);

The benefits of working in this way are many, but to name a few:

  • It's shorter and more readable
  • It executes faster, and so is more optmial at runtime
  • Certain common types of errors are checked at compile-time (typos or incorrect params)

Hope this helps!

---- EDIT ----

Apparently it didn't so here's another thing to try:

If your enemies are being dynamically instanced, then having a reference to the LevelController prefab sounds wrong - they ought to have a reference to the instance of that prefab in the scene.

I understand the problem is that you can't drag in these references because when in edit mode, the enemies don't exist in the scene in order to be able to drag references into them.

There are two ways that spring to mind to solve this:

  1. Have the script that instantiates the enemies "tell" the new instances about the LevelController reference. Or...

  2. Have the enemy instances "find" the LevelController reference in their own start functions.

To implement number 1, you would have a reference to the LevelController object in your "EnemySpawner" script (or whatever it's called - the important thing is that this presumably is on a gameobject somewhere in your scene).

In this script, it creates a new enemy instance, and then immediately after, in the same function, it passes the LevelController reference it has to the enemy, like so:

var levelController : LevelController;

// "Enemy" is the name of the script on your enemy prefab var enemyPrefab : Enemy;

function SpawnEnemy() { var newEnemy = Instantiate(enemyPrefab, newPos, newRot);

 // now the levelController var on the new enemy is assigned the
 //  same reference that this script currently holds:
 newEnemy.levelController = levelController;

}

Alternatively (number 2) - this is one of the situations where using one of the many "Find" functions is a good idea. You could find the levelController by the name of the gameobject, by its tag, or by the type of script attached.

Seeing as you know there is only one of this kind of object in your scene (or there should be, right?) you can make your enemys find this object using a single line of code in their Start function:

// this var is "private" because it doesn't need assigning externally private var levelController : LevelController;

function Start() { levelController = GameObject.FindObjectOfType(LevelController); }

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kristov · Dec 02, 2010 at 08:27 AM 0
Share

Although I prefer your method vastly, it still has the same problem. Perhaps this has something to do with it, although i don't really think so: The enemies are instantiated from prefabs, and the prefabs have the script (it's called Scoreboard; the Game Object is called LevelController) referenced. However, since an object only in the scene can't be referenced in a prefab, I had to make LevelController a prefab and reference that.

I initially thought that was the problem, but I don't think it explains why it calls the function properly, and just doesn't send the value along... Does it?

avatar image duck ♦♦ · Dec 02, 2010 at 11:39 AM 0
Share

(added extra info based on your comment)

avatar image Kristov · Dec 07, 2010 at 03:42 AM 0
Share

Excellent! Finally got it to work, using the second method; thanks so much, I was at my wits end!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

What is the best way to call a function from another script 1 Answer

How to call a function from another script without referencing it? 1 Answer

How to reference another script and call a function in C# ? 2 Answers

Calling a function from a different script on the same object 1 Answer

Sendmessage - return value 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges