Difference btw. sendmessage and setting Value - unity3d

What is the difference between those two methods? Why should i prefer one?
1)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().active = true;
2)
GameObject.FindGameObjectWithTag("").GetComponent<Rocket>().SendMessage("setActive");
thanks!

Sending a message searches through all the components of the gameObject and invokes any function that has the same name as the message. Not a 100% sure but Im sure this uses reflection which is generally considered slow.
SetActive() or the active variable set the gameObject as active or not. If its not active it wont render in the scene and vice versa.

First of all it seems there are several inconsistencies with your code above:
1) Components (and MonoBehavior) don't have an active property (active belongs to GameObject), so the first line of code shouldn't compile. In addition the most recente version of unity don't have active anymore, it's substitued with activeSelf and activeInHierarchy.
And btw, both activeSelf and activeInHierarchy are read only, so you can't assing directly a value to them. For changing their value use SetActive method.
2)
The second line of code shouldn't work either (unless Unity does some magic behind the scenes) because SetActive methods belong to GameObject and not to your Rocket Component.
Now, I suppose your question was the difference between:
gameObject.SetActive(true);
and
gameObject.SendMessage("SetActive",true);
The result is the same, but in the second way Unity3D will use reflection to find the proper method to be called, if any. Reflection has an heavy impact on performance, so I suggest you to avoid it as much as possible.

Related

Unity3D get an Object in start Method

Hey im trying to get an object which is referenced in another script (dictionary).
But when i try to get the object in the start method it seems like the dictionary isnt populated jet.
Error: NullReferenceException: Object reference not set to an instance of an object
If I run this line of code in the update method it works completely fine.
Is there an easy way to let this line run after the dictionary is populated?
Grid Manager Script
Camera Movement Script
Both your code snippets run in Start.
There is no way to predict in which order these two Start messages will be invoked (at least not from the user perspective).
To solve this kind of race conditions (see Order of execution for event functions).
The Awake function is called on all objects in the Scene before any object's Start function is called.
my general thumb-rule is:
Use Awake
to initialize the component itself where it doesn't depend on values
from other components.
E.g. initializing your fields, filling your collections, using GetComponent etc to initialize references (but stop there)
Use Start to then initialize things where you do depend on other components being already initialized.
Like in your case access the collections of the other component
This usually covers most of the cases.
In your case simply converting GridManager.Start to GridManager.Awake should already solve the issue.
Where this is not enough you either can start and tweak the Script Execution Order and basically enforce a certain order in which the event methods get invoked or implement a more complex event based initialization system
Populate the dictionary in Awake() method instead of Start(), then it would be ready by the time you need it in Start() of another script.

Why is "Cast to BP_Ladder" failing all the time?

I am having trouble with my Unreal Engine 4 project. I'm very new to this and i don't really understand what's going on. I have made ladder functionality so the character can climb up the ladder and stand on the Static Mesh that is on top. But when i want to go down the ladder i want to trigger the "Allow Down" function on Actor "BP_Ladder" but the cast is failing everytime. what is causing the casts to fail?
I've looked around and other people with cast failed problems have mostly had the names wrong but my ladder is called "BP_Ladder" and that is what i'm casting to so that leaves me really confused.
My BP_Dude blueprint (this is being called every tick)
My BP_Ladder blueprint (this is what i'm trying to trigger)
The goal for this function is that the collision of the static mesh will turn off and then allow me to move down the ladder like normal.
I'd really appreciate your help with this, its my first couple of days using unreal engine and the Epic Games tutorials i followed didn't show all of the blueprints so everyone was left helpless with half broken blueprints.
Understanding Casts
In its simplest form, if your Actor can be cast to BP_Ladder, then it will return the casted object on the output pin.
Just to ensure you know how a cast works, I have to point out that you can't cast a given type to some unrelated arbitrary type; it has to be "castable" to the cast destination. So if you think that the Actor object returned by your overlap is genuinely a BP_Ladder, or a blueprint class that derives from BP_Ladder, then you should be OK. But that has to be the case; otherwise it will fail every time.
https://docs.unrealengine.com/en-us/Engine/Blueprints/UserGuide/CastNodes
Sorry if I'm being patronising, but if a cast isn't working 9/10 it hasn't been used correctly.
Debugging
OK that out of the way, if you think you are genuinely casting to the correct type and it's still failing, then you'll need to debug your blueprint with the objective of finding what type is being given to the cast node which results in the failure.
Select the cast object in your blueprint.
Press F9 to create a breakpoint; a red circle should appear on the top left of your cast box
Run your game in PIE mode (Combo next to play, New Editor Window (PIE))
Put the game in a scenario where your cast will fire (I presume touch the ladder)
The breakpoint should trigger; your game window will go grey and you'll get a large red arrow pointing down towards your cast box where you placed the breakpoint
Hover over the Object pin on the input side of the cast box. It should show a alt-text containing details of the variable.
Inside the alt-text box, look for Current value; this should show you the current object type that you are about to cast. You need to ensure that this value is what you expect.
https://docs.unrealengine.com/en-US/Engine/Blueprints/UserGuide/Debugging
Example
I've taken a screenshot of a working game; in this you will see:
a Breakpoint (the red circle) is shown on the function node (the box)
the Execution node (red arrow) is Create Rolling Stock
the Current value of the variable is DepotComponent...Depot
Final thoughts
There's a couple of gotchas when using blueprints; one of them in this case could be that you can have two classes with the same name (although they might have different internal "script names" - effectively a fully qualified path). When you debugging an object variable, make sure you match the entire path to the location of your asset in your content folder; this will ensure that you are indeed attempting to cast to the object you think you really are.
Another classic gotcha is "hot reloads". Sometimes the editor needs to reload a module after an on-the-fly build but a class conflict occurs internally; this results in the new version of the class getting a different name (prefixed with HOTRELOADED). Watch out for this; it can cause you to be dealing with two distinct types when casting and you don't even realise. A real sanity-sapper. If in doubt, close and re-open the editor; it fixes it every time.
On Begin Overlap is only triggered when you START an overlap, so if you have some logic that sets your "can climb" to false you will need to move outside of the collider and back into it again for another Begin Overlap event.

Transparent layer Unity

In my scene I have 2 camera(split screen). it's possible change the trasparency of a layer only for one camera? for examples the "layer1" have alphatrasparency = 0.5 for right camera while left camera show "layer1" without trasparency.
Ostensibly no
There's a way to do it, though. It's a bit of a hack though, as it doesn't depend on physics layers, but rather the presence of a custom monobehavior script. Here's what I remember about this off the top of my head (I can dig up an implementation later, if needed).
Step 1: you will need a MonoBehaviour script attached to every game object you want to have rendered differently. This script is absolutely essential.
Step 2: this script will contain one function (you can use an existing behaviour script if all the objects already have one in common and you can just add this function to that script). Call it whatever you want, but something like AboutToBeRendered(Camera cam)
Step 3: create another script and attach it to both cameras. This script will also have one function in it: OnPreRender()
Step 4: In this OnPreRender method you will need to do:
find all game objects from Step 1
get their component with the AboutToBeRendered method
invoke that method, passing the camera as the paramter
Step 5: Writing the AboutToBeRendered method.
determinie which of the two cameras was passed to the method
set the material's color to be transparent or not, as needed
OnPreRender() is only called on scripts with a camera component on the same GameObject, indicating that this camera is about to render the scene. But what we actually want is for the object about to be rendered to know that it's about to be rendered and by which camera. Which is why we need the script in step 1.
I suppose you could skip step 1 and only look at every object in the scene and look at its physics layer, but that's going to be more expensive to figure out than "get me all instances of this component." You could do it based on Tag instead, as FindObjectsWithTag is generally considered to be pretty fast, but if you're already using the tag for something else, you're out of luck, and there's no comparable method for getting objects in a given physics layer.
However, you'd have to tweak the material's alpha value in the camera script rather than letting the object itself decide what value it should be.
In either case, the object's material would need to support transparency. When I did this I was preventing the object from being rendered entirely, so I just disabled its MeshRenderer component.

Interacting with events and listeners in MATLAB

I want to write GUI code that is orthogonal. Lets say I have a circle class and a square class and they need to interact. Right now, to get the circle and square talking to each other - say the circle object sends a message to the square object, I would use something like square_obj.listen_for_circle(circle_obj) where listen_for_circle is a method that implements an addlistener.
This is a problem for me since now the two objects are linked - and removing one object from my code would break it. What I am looking to do is for the circle_obj to be able to broadcast a global message say 'CIRCLE_EVENT'. Additionally square_obj would be listening for global message broadcasts of type 'CIRCLE_EVENT', and upon hearing the event - does some action.(Ahhh, now the objects have no links to each other in the code base!)
Is this possible or even reasonable in MATLAB? (or maybe i'm just going crazy).
As always, advice much appreciated.
I'm not really sure why addlistener is problematic for you. It basically just adds an event listener that doesn't do anything if the event-origin object (the circle) is deleted.
Alternately you can use event.listener or handle.listener. They are undocumented but work well, and are widely used within the Matlab codebase (m-files). See explanation here: http://UndocumentedMatlab.com/blog/continuous-slider-callback/#Event_Listener

Rhino Mocks Calling instead of Recording in NUnit

I am trying to write unit tests for a bit of code involving Events. Since I need to raise an event at will, I've decided to rely upon RhinoMocks to do so for me, and then make sure that the results of the events being raised are as expected (when they click a button, values should change in a predictable manner, in this example, the height of the object should decrease)
So, I do a bit of research and realize I need an Event Raiser for the event in question. Then it's as simple as calling eventraiser.Raise(); and we're good.
The code for obtaining an event raiser I've written as is follows (written in C#) (more or less copied straight off the net)
using (mocks.Record())
{
MyControl testing = mocks.DynamicMock<MyControl>();
testing.Controls.Find("MainLabel",false)[0].Click += null;
LastCall.IgnoreArguments();
LastCall.Constraints(Rhino.Mocks.Constraints.Is.NotNull());
Raiser1 = LastCall.GetEventRaiser();
}
I then test it as In playback mode.
using (mocks.Playback())
{
MyControl thingy = new MyControl();
int temp=thingy.Size.Height;
Raiser1.Raise();
Assert.Greater(temp, thingy.Size.Height);
}
The problem is, when I run these tests through NUnit, it fails. It throws an exception at the line testing.Controls.Find("MainLabel",false)[0].Click += null; which complains about trying to add null to the event listener. Specifically, "System.NullReferenceException: Object Reference not set to an instance of the Object"
Now, I was under the understanding that any code under the Mocks.Record heading wouldn't actually be called, it would instead create expectations for code calls in the playback. However, this is the second instance where I've had a problem like this (the first problem involved classes/cases that where a lot more complicated) Where it appears in NUnit that the code is actually being called normally instead of creating expectations. I am curious if anyone can point out what I am doing wrong. Or an alternative way to solve the core issue.
I'm not sure, but you might get that behaviour if you haven't made the event virtual in MyControl. If methods, events, or properties aren't virtual, then I don't think DynamicMock can replace their behaviour with recording and playback versions.
Personally, I like to define interfaces for the classes I'm going to mock out and then mock the interface. That way, I'm sure to avoid this kind of problem.