Unity2d - Destroying Object using Destroy(gameObject) // it will destroy the object with which the script is attached to - unity3d

I am Creating Unit2D game & i am new to it , where i have written code for Destroying Player Bullete when it hits to Meteorite(or enemy).
I have one Bullete PREFAB. to which Destroybullete script is attached. where i have written normal code under TRIGGER function (C# script).
void OnTriggerEnter2D(Collider2D col)
{
if(col.gameObject.tag == "meteorite") // have given meteorite tag to meteorite PREFAB
{
Destroy(gameObject)
}
}
I want to know is it correct way to destroy any object. because it keeps showing me msg that "Avoid destroying object to avoid data loss".
AND THE MAIN THING.
This code works well in Unity Editor ( Build Settings set to android).
But if i build and create APK of it .......... on my android mobile(redmi 1s) , it is not working.Bullete starts firing automatically ( as required) but as any bullete hits meteorite than game lags for miliseconds and bulletes stops firing....AND THE SAME CODE WORKS FINE UNDER UNITY.
DOES TO MEAN I HAVE KILLED bullete prefab for ever by writing Destroy(gameObject).
need Explanation and solution for correct way destroying objects.

The correct way to destroying objects is not destroying them :).
The msg you are getting in console inside Unity is just a warning to try avoiding destroying objects, main reason is being that Destroy and Instantiate are VERY expensive commands and they are often used a lot (like your example, instantiating every bullet then destroying it).
Reason why it works well on PC is because you have much higher processing power of hardware compared to mobile and the lag you are getting on mobile is the time it takes to finish Destroy command (or Instantiate).
The way you can avoid using Instantiating and Destroying objects is by using object pooling, it is a simple way to reuse small pool of objects.
Here is a simple way how you would implement it:
1. Instantiate let's say 5 bullets at start and hide them inside barrell or something like that.
2. Fire the first bullet from barrel and when it hits something just move it back to barrel at the end of array.
3. Keep reusing the bullets
You have good in-depth explanation about object pooling here : https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/object-pooling
But you can get away with much less understanding of object pooling, if this is too long try searching online something like "Unity3D object pooling" and find simpler tuorial.

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.

Unity 3D: what is the correct way to detect that the collision has already been processed for another collision participant?

I have a class CollisionHandler which has the OnCollisionEnter method. Each collideable entity in the game has CollisionHandler as a component. So, when 2 objects collide the OnCollisionEnter method is called twice and it's ok because the damage and other things are processed as a result of touching object "B" by object "A" and vice versa.
In addition, each collision creates a flash effect and plays a sound of impact and of course, these effects are also played twice for each collision. Although it wouldn't be imperceptible to the player it doesn't seem to be correct anyway. In order to prevent it, I came up with the following solution: I save the current frame number in another collision participant so it will know that these effects have been played already by the first one.
private void OnCollisionEnter(Collision collision)
{
// Calculate the damage caused by `this.gameObject` to `collision.gameObject`.
// ...
// Play an impact sound and show a visual effect.
if (thisObject.CollisionFrameId != Time.frameCount)
{
otherObject.CollisionFrameId = Time.frameCount;
// play sound
// show hit effect
}
}
Although it works I'm not sure (I'm a novice in Unity) that it's the best practice and if so please suggest other possible solutions.
Note that I didn't ask "Why is OnCollisionEnter getting called twice?". I know why it happens. My question is about the other, though it does mention the name of the same function it still doesn't asks the same.
You could do a GetComponent on the other object with one of your scripts (or the same script) and set the RecentCollisionObject to the current script or gameObject (and maybe a given time frame just for additional safety (if only one triggers it, but not the other for some reason)).
On each collision you check if RecentCollisionObject is the other object (and if no more than ~0.01 seconds has passed). If true, you know that particular collision must already have been processed by the other object just now, so reset all values from that other object and do nothing else. So the next collision which occurs, no matter how soon, will do this cycle anew and work as expected.
This way you let only the first to trigger the collide code execute your code (like a sound). The point is that both collision events are ran in the same frame, so no matter which triggers first, you can prevent the second from running.
You can use the Unity Tag System, you tag action to occur when colliding with that specific tagged object.
As example:
internal void OnTriggerEnter(Collider other) {
if (other.gameObject.tag == "Oject Tag") {
this.GetComponent<AudioSource> ().PlayOneShot (objectTagSoundClip);
}
Just need a audio to play placed in game object.
Maybe you have 2 Colliders. If so you could check if boxcollider for example is colliding only. You could also try on Collision leave. Hope it helps.

UE4 Objects overlap position after collision

I'm new to unreal engine, I'm trying to add large force to an object with a box collider but after it collide with other object (just another instance) the overlap inside each others and become like one object and moving with each others.
Cab anyone explain their behavior and how i should resolve this?
What happens here is that both objects collide with each other continously. To fix that you could try to deactive the OnOverlap()-Event on either the overlapping Object or the colliding object.
In blueprints you can achieve that by setting the Generate Overlap Events-Variable of one of the colliding static meshes of the overlapping objects to false.
In C++ you could simply remove the dynamic event callback for one of the colliding objects like that:
CollidingComponent->OnComponentBeginOverlap.RemoveDynamic(this, &ACollidingActor::OnBeginOverlap);
Where CollidingComponent is the component of your object, which causes the overlap event to trigger.
Like #Alex said, they overlap with each other, over and over. If you didn't know, you can add breakpoints to your blueprint nodes, just like in your code, by right-clicking a node and select Enable Breakpoint (or smth like that). Your game will stop when reaching it and switch to that exact point in your blueprint. You can then hover over that node and see every variables value going in and out of it.
Hope this helps you learing to use the Unreal Engine.

Using a timer vs update to run game SpriteKit

I am curious what to use for my game. A timer:
let goodFPS = SKAction.wait(forDuration: 0.01666)
let mainGameRunner = SKAction.run {
//my code is here
}
let toRepeat = SKAction.repeatForever(SKAction.sequence([goodFPS,mainGameRunner]))
inGameHighScore.run(toRepeat,withKey:"mainGame")
or the update function:
override func update(_ currentTime: TimeInterval){
//my code is here
}
Which provides faster more consistent updates?
note: my frame rate is in the range of 45 to 58
First I think you are taking the FPS problem the wrong way around. You cannot "force" a faster frame rate than the device can give you. If you are basing the movements in your game on the assumption that every frame will be consistent, you are doing it wrong. It's actually how they did in the early days because CPUs were so slow and the difference from one generation to the new one wasn't too bad at first. But running an old DOS game on younger hardware will be tricky because the framerate is so high that the whole game mechanic becomes unstable or simply too fast to be playable.
The concept here is to think "over time" and to scale down any action in relation with the time elapsed between two frames.
The update() method gives you that opportunity by providing the current system clock state every frame. By keeping track of the time on the last frame, you can calculate the time difference with the current frame and use that difference to scale down what you are doing.
Using a timer to get the update on a consistent frame rate is not recommended nor practical. You may be calling the update closure at a given time interval, but the code inside that closure is taking time to execute on its own, and depending on your game logic, it might even have different execution times. So maybe the pause timing is consistent, but the code running before and after that pause might not be consistent. Then what happens if you run your game on a slower CPU? The code speed will change even more, making your timing inaccurate.
Another point against using an SKAction for your game loop is simply what they are. An action is an object in memory, meany to be reused by multiple objects. If you are making a "jump" action, for example, it is recommended to store that action somewhere and to reuse the same object every time you need something that "jumps", no matter what node it is. Your game loop is meant to be executed every frame, but not by different objects. Actions are also disposable. Meaning that you can kill an action even while it's running. If you put your game loop in an action, it will probably be run by the SKScene. If you use another action on your scene it becomes a puzzle right away because there are only two ways of removing an action besides letting it come to term: removing all actions or creating the action with an identifier key and use that key to remove any action with that key. If you don't see it already, it then forces you to put identifiers on every action that will be run by the scene and remove them one by one. And them again it leave a door open for a mistake that will get rid of your game loop because, keep it in mind, actions are DISPOSABLE! Then there is also no guarantee that your action will get executed first every single frame.
Why use the update() method? Simply because it is built IN your scene. No matter what, every frame, update() gets called first. THEN, the actions get executed. You cannot flush the update() method accidentally like you can with an action. You don't have to be careful about strong/weak relationships causing memory leaks because you are referring to objects from inside a closure like you do with an action.
Suggested reads:
SKAction API reference
SKScene API reference : read about the frame processing in SpriteKit. It will help you understand how they put everything together at every frame.
I hope it makes things clearer.
I'm pretty sure that SKAction's timing facilities are based on the same game loop that is calling update.
The advantage of SKAction is that it's fire and forget for you, while using update would get awkward with setting and checking a bunch of timer variables.
I don't have a ton of experience with SpriteKit but I do have some experience making games and animations in iOS.
There is a class called CADisplayLink that fires a call to a delegate every time the screen is refreshed, this is a great way to update the screen, either in a game or in an animation, because you can know it will be called every frame and no more.
I'm not sure if SpriteKit uses that class to fire the update method, but I'm sure it uses something similar. This is usually called the run loop.
SKActions run on top of this run loop.
By creating your own run loop using a wait action, not only you're not gaining any benefits, you could be introducing inconsistencies in the way your logic is run.
Imagine that you have your wait action set to 0.01 seconds (I rounded it down for simplicity). If the screen is refreshing faster than you expect, and the action is updated every 0.009 seconds, the first time it's checked, it won't fire because there's a remaining 0.001 second on the wait command, so another 0.009 seconds will pass, and your code will be executed after 0.018 seconds, instead of your desired 0.01. Not only that, but two frames will have passed between the execution.
If you use the update function, you can know that your logic will be executed once every screen refresh, and no more.

Loading Next Level

I am making a game in Unity. There are currently two levels. I count to 30 seconds, when the time becomes 0, I want to load the next level automatically. But when the next level is loaded, the game screen freezes and I cannot move anything. The function I used to load the next level follows below (this function is in a script which an empty game object which will not be destroyed when loading a new level carries):
function loadNextlvl(){
var cur_level = Application.loadedLevel;
yield WaitForSeconds(5.0);
Application.LoadLevel(cur_level + 1);
}
What should I do?
My work with Unity has been hobby-driven only, but anytime I've used Application.LoadLevel I passed it a string of the level name, rather than a pointer. I see from the API that it's overloaded to take an int as well, but maybe for testing purposes, call it by name to see if that works.
Also, you need to tell Unity the levels you're going to be using. You can do this in the Build Settings off the file menu.
Lastly, you can try using Application.levelCount to see if you're within the bounds of levels.