Unity 2D OnTriggerEnter2D() will not repeat in an entirely different script - c#

I am creating a game where there are 9 chunks in 1 2D map and you must "unlock" every chunk by triggering a collider on the edge in a specific order to beat the game. I have managed to switch the scene from 0 to 1 using this code on a rectangle with a trigger collider:
void OnTriggerStay2D(Collider2D other)
{
SceneManager.LoadScene(1);
Destroy(this.gameObject);
}
The code above works fine, but recently I created the third chunk and copied the code to a new script, changed the name, and switched SceneManager.LoadScene(1) to SceneManager.LoadScene(2), then added it to a new rectangle with a trigger collider. The second chunk loads in when triggered, but the third does not. Is there any way to fix this?

I don't have enough reputation yet to comment, so I'll propose a few possible problems/solutions. I assume your chunks are scenes, so you're loading in several scenes at once? Some things I can think of that might be causing the second chunk not to load in:
Did you add the scene to the build? If not, you can do so in the build settings.
You can try to debug OnTriggerStay2D() in the second chunk trigger. Is it being triggered? If not, you might not have added the trigger to the rectangle correctly: did you set up the Rigidbody2D?
If the above points do not fix your issue, I'd suggest adding more of your code (of the chunk loading scripts) and some screenshots (of the inspector in both chunk loaders and of the colliders you made) to your question. Hope this helps.

Related

OnTriggerEnter2D working only when the game starts, i want it to check for collisions every frame

I am working on a game in unity, a type of sliding number puzzle where you have to line up each piece in ascending order. My code of checking collisions is only working when I start the game, so if I move a piece, it won't tell the near pieces that I moved the near piece. I hope you understood my problem, every help is appreciated. Thank you.
This is how my code looks with the up check. I
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "Piece" || collision.gameObject.name == "Up_Collider")
{
piece_Script.Collide_Up = true;
Debug.LogError("Up");
}
else
{
piece_Script.Collide_Up = false;
}
}
I Thought that the else statement will solve this problem but it didn't.
Make sure all the things I write below are correct in your project:
1- You are using "2D" colliders on both objects.
2- At least 1 of the objects has a "Rigidbody2D".
3- IsTrigger Checkbox is active in your collider.
4- You are using the correct Tag.
5- Check layer collision matrix in - Edit > Project Setting > Physics2D.
And it is better to use tag instead of name
Based on your code in your question and your video, I see at least a couple issues.
First, there's an issue with how you're moving pieces. Your movement code for a Piece is:
Piece.transform.position = Vector3.Lerp(a, b, t);
This is not correct if you want to trigger collider events. These require interactions with rigidbodies, which means you should instead be changing the position of the piece's rigidbody with Rigidbody2D.MovePosition(). This will move your rigidbody within the physics system, which means taking into account collisions/triggers.
So (assuming you get the rigidbody for each Piece when you initialize them), your code might look like:
// Note also that I used Vector2 here - it's best you keep it consistent
pieceRigidbody.MovePosition(Vector2.Lerp(a, b, t));
Second, OnTriggerEnter2D() is not fired when two colliders stop touching. So I don't see your "else" condition being particularly useful. To achieve that with your current code, you could theoretically introduce OnTriggerExit2D() to take care of the "else" condition. However, you run into complications because while moving, a Piece may Enter and Exit the same directional colliders of two other Pieces before coming to rest. You'd have to take into account the order that occurs to get an accurate final state.
While workable, I have an alternative approach to suggest: Abandon using Trigger Collider events, and only check for a valid move at the time a Piece is clicked. Eliminate the collider event handlers, and just execute a Physics2D.OverlapBox() in each position around a Piece when it is clicked. If the position is occupied by another piece or an edge, that's not a valid move. If there is a position without something blocking it, then move the piece there.

Unity Rigidbody has velocity but not moving

I have a game in Unity where cubes are repeatedly moved past the camera. I move the cube using a script where I set its Rigidbody's velocity each update. Once it moves out of view my script instantiates a new cube on the other side which begins the process again.
Recently I've found that it works fine for a random amount of cubes before, seemingly randomly, a cube is instantiated that does not move. Using the inspector I can see that this object has velocity. If I move it even a small amount using the editor it starts to move as normal.
Has anyone seen something like this before?
I'm fairly certain the problem was related to the fact I was trying to directly modify the velocity( The physics engine decided the object was at rest and stopped it moving. ). By setting the object to be kinematic and modifying its position in my code I solved the problem.
May be you are changing the velocity of your gameObject when it goes through a specific coordinate (in an if statement for example), unity is not very accurate sometimes with coordinates so it may be happening that the condition is never met. Change that condition and add a margin range to solve this error.

unity2d loading large worlds

I am using the unity engine to make a "open world" (I'm using this loosely because its mostly the same) MMO top-down shooter. I have made the world, I have a really fast system to only load the part of the world you are standing on, But It still takes 5 or 6 minutes for it to load from the play button. basically what i have done is have a massive grid of tiles split up into 8x8 sections, and those into 12x12 regions. I would like a way to load the world as you go (like from a bitmap image or something), but would I also want to be able to edit and change the world in the editor. Anybody who has done this before can you help me figure out what to do?
Just off of the top of my head, I haven't used this in a released product but you can split your large scene into multiple scenes, you said you 8x8 tiles by 12x12 regions.
I would suggest making a base scene, that loads where the player is in the world, based off of his position you load a scene and a few scenes around him, as he navigates the world or gets to a place you determine would be in range for him to see other items you load the next scene. This is what it would look like:
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOXXOOOO
OOOOOXXXOOOO
OOOOOOXOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
each O represents a scene, and the X's are loaded scene. How do you load multiple scenes at the same time? If you take a look at the overloaded methods for SceneManager.LoadScene there is a method that takes in a LoadSceneMode Passing LoadSceneMode.Additive Will load a new scene into your world. without unloading the previous scene. So depending on how intensive your game is, you could Just load the surrounding area's to the player and load them over time in the background. The other option is to hold which scenes are currently loaded.
Next issue, being able to edit and change the world in the editor. Inside of the Unity Editor you can have multiple scenes open at once, and move and relocate each item in those scenes. The scary thing about this though, is to add a new GameObject to a specific scene you have to have that scene set as the active scene.
Here is a link to the documentation on Multi-Scene editting:
https://docs.unity3d.com/Manual/MultiSceneEditing.html
Documentation on SceneManager.LoadScene:
https://docs.unity3d.com/2018.1/Documentation/ScriptReference/SceneManagement.SceneManager.LoadScene.html
Documentation on LoadSceneMode.Additive:
https://docs.unity3d.com/2018.1/Documentation/ScriptReference/SceneManagement.LoadSceneMode.Additive.html

Changing Sprites using scripts in Unity2D C#

I am wanting to make a birds-eye view pixel-art game.
I currently have two sprite sheets set up, and split and whatnot
groundSheet and characterSheet these are split up into
ground_0_0_0 (A concrete floor)
ground_1_0_0 (grass)
character_0_0_0 (man idle animation frame 1)
character_0_0_1 (man idle animation frame 2)
character_0_1_0 (man run animation frame 1)
character_0_1_1 (man run animation frame 2)
character_1_0_0 (woman idle animation frame 1)
character_1_0_1 (woman idle animation frame 2)
character_1_1_0 (woman run animation frame 1)
character_1_1_1 (woman run animation frame 2)
The numbers after are a note as to:
first number - the main set of sprite animations (eg man)
second number - the animation set in use (eg run or idle)
third number - the frame of said animation.
(the ground has this as i plan to have animated grounds late on)
Now, I wish to make a script for the character (and ground alike) that has an editable value that is view able in the unity editor, for example how things like the sprite renderer has sprite, colour etc. Which dictates what first number to use (see above) what second number and the delay for the animation of the third number. This will then tell the sprite renderer what pictures to load and how quickly to load them. I also wish for the script to scan for the file starting with for example character_0_0_ and then count how many files after it, so it knows what to do when animating. I would like this script to be checking for a change in one of the variables viewable in the unity editor to change and as soon as it does it checks everything it needs for an animtion.
Something else could be done where there is only 1 box to edit in unity, which you put character_0_0_ or ground_1_0_ or something similar, and it checks everything that way (it also makes the script universal, and usable on the ground, character and walls (which I am adding later)).
This may seem confusing, but it make sense for me and many of you will probably mention a much easier way to do animations and such, but please only say these if it does what I want above.
For scripts and such my file layout:
/Assets
/scripts
ground.cs
character.cs
/sprites
characterSheet.png
character_0_0_0
character_0_0_1
character_0_1_0
character_0_1_1
character_1_0_0
character_1_0_1
character_1_1_0
character_1_1_1
groundSheet.png
ground_0_0_0
ground_1_0_0
(For some reason Stack overflow said the above was code, so i had to make it as that)
ground.cs and character.cs are the scripts in which I want to made as explained above.
In my object view thingy I have
Main Camera
ground
character
I am practically a newb to C# and JS I know bascially the grammar of C# (like where to use {} and put ; at the end of the lines). If you help me with this, i request that you explain the script, like use the // thing to simply explain what each command does, I know a few but not all of them. And I know someone is going to say it is really well documented in tutorial X and such, but most tutorials are not in unity 5 and while helping with the matter do not touch on it exactly.
Thank you for your help, if there is anything about this question/request that you do not understand (It is pretty complex) I will explain.
Maybe I am completely wrong, but it seems to me that you are trying to recreate an Animation system.
Is there a specific reason for which you wouldn't use Unity's animation system?
You can do everything that you describe here with it (change sprite, choose animation speed). And you would have almost no code to write. Just drag and drop you sprites in the editor for a start
EDIT - answer to first comment:
What you should do is create all the animations you need. Then in the animator, you choose which condition will trigger a transition to another animation (for instance, boolean jump is true will transition to animation jump). Then in your code you can call GetComponent().SetBool("Jump", true).
To have different character, you can create different gameObjects (one per character). They all have a different animator with animations specific to the character.
The other solutiojn if you really want one one gameObject and one animator is that you also add string condition to you animation (example, if character=="character1" and jump==true, transition to jump animation).
If I were you I would really focus on testing and learning all you can do with Unity animator. I can't think of a case were you would need to recreate the animation system yourself
Your question was long winded and hard to understand but ill try to help,
firstly if you want editable values in the unity editor I would Suggest using a serialized structure of information like this
[System.Serializable] // this makes it viewable in the inspector
public struct Sprite_Manager;
{
public Sprite[] Render_Sprites; // array of sprites to store sprites
public SpriteRenderer S_Renderer;
public float Anim_Delay;
}
public class Character : MonoBehavior {
Sprite_Manager SMG = new Sprite_Manager(); // instantiate a new instance of the struct
void Set_Sprite()
{
for(int i = 0; i < SMG.Render_Sprites.Length; i++)
{
SMG.S_Renderer.sprite = SMG.Render_Sprites[i];
}
}
void Update
{
Invoke("Set_Sprite", SMG.Anim_Delay);
}
}
Not sure if this is exactly what your looking for but this is one way you could setup a structure of sprite based information and use Invoke to setup some sort of delay when passing new sprites to the renderer.

Trouble with Rectangles overlapping instead of touching XNA 4.0

I'm making the skeleton for the typical BubbleShooter game in XNA, and I'm having issues with my collision detection algorithm, which is explained in the picture here
Depending on where the colliding Rectangle position is at the moment of collision, a new position is assigned to the colliding Bubble.
The issue appears when I shoot a bubble and this happens at the moment of collision.
I have run the debug step by step, and the moment when the collision happens is exactly like the picture, so my algorithm fails.
I tried to post the images directly, but it seems I can't since I'm still a new user here. Sorry about that.
Is there a way I can detect exactly when the boundaries of the Rectangles touch each other?
You can perform a per pixel collision instead, it is explained here:
Click here
So, if I understand, your problem is that you miss the exact moment of collision ?
I guess you are computing collisions in a discreet way, ie. even if your algorithm runs 60 times a second, it is only 60 times when a second could be subdivised in an infinity of instants.
The simple (and bad) solution is to make your objects move slower.
The good one implies to retrieve what happens between the frames. you will need some kind of direction vector and the object speed. With both these values, you can determine where and when the collision did occur.
You will also need the elapsed time between frames. This is the purpose of the GameTime object : it has a property "ElpasedGameTime", which has a property "TotalElapsedMilliseconds".
MSDN Documentation on GameTime class : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gametime.elapsedgametime.aspx
Some reading material on Wikipedia about collision detection: http://en.wikipedia.org/wiki/Collision_detection#A_posteriori_.28discrete.29_versus_a_priori_.28continuous.29
"A priori" and "A posteriori" detection : that's the keywords you might be missing.
I don't have time to test it right now but you should try to limit your number of collisions per frame to 1.
With a counter when it enters the update part if one collision has been detected block all other collision for the same frame.
This way if your projectile its the bottom part, your code for
if(hitBottomPart)
{
// Logic
}
part will execute in this same frame before the projectile has time to hit another rectangle of the texture.
Although this is just a guess.
Good luck with your game ! Collisions are always a pain to implement.

Categories

Resources