I have Been Developing a game, I am having problems with the collision part of this game, and I'm not sure how to fix it
private void timer1_Tick(object sender, EventArgs e)
{
List<Obstacle> removed = new List<Obstacle>();
foreach (Obstacle o in obstacles_)
{
Rectangle bounds = o.Bounds;
if (players_[0].Bounds.IntersectsWith(bounds))
removed.Add(o);
}
foreach (Obstacle ob in removed)
obstacles_.Remove(ob);
}
Basically what I need it to do is if the player runs into an object, then it will remove itself from the list and stop being drawn on the form.
EDIT - Realised I haven't really said what the problem is, When the object collides, it doesn't remove itself, and continues to be drawn
Edit - 2 FIXED - See comment below!
My first guess would be that you're using a different list of objects in the draw step than in the collision step. If you're removing the objects from obstacles_ but in the draw step you iterate through objects_, for example, the objects would still be drawn.
Another problem could be if the obstacles_ list is rebuilt every step. I would suggest stepping through this block, make sure the objects are actually removed, then checking the draw step and see if the list is up to date (the object is gone). If you can, start with one obstacle to make it easy on yourself.
Okay guys, thanks for all the help, I have managed to figure it out, I was creating the bounds in the obstacle class at the start of the code, but then as it updated its position the bounds didnt update...
Seem sorta foolish but I think ive got it all sorted now.
Thanks for everyone that tried to help!
Related
I have a building grid system in Unity that is based on the TileMap system that already exists. I have systems for placing objects by clicking, and randomly generating objects that also get placed. Placing an object paints the tile a different color to indicate that it's placed.
I'm trying to make a system where you can remove placed objects, which means that the tilemap also needs to be updated to reflect the removal. This doesn't work at all, and creates some issues that I have never encountered and I have no idea how to solve.
I have a function that paints the tiles, and it goes like this:
public void TakeArea(Vector3Int start, Vector3Int size)
{
MainTilemap.BoxFill(start, tileName, start.x, start.y, start.x + size.x, start.y + size.y);
}
This all works for placing, but when I try to do it using an OnClick function, I get some errors. The "start" and "size" are passed on correctly, and when printing the values for the area, I get the correct ones. The problem is with the "tileName" variable this time, as it randomly becomes "Null" when I try to print it, even though in the game itself I an see that the assigned value is not "Null", but it references a tile that should be painted.
I have tried so many things for a couple of hours, but I think I finally found a solution. I made some adjustments to that function so that it's exactly the same as it is when an object is generated, as that already works, so I'm first Instantiating the object with this code:
GameObject oreObj = Instantiate(prefab, poss, Quaternion.identity);
Then I will get the object position and size from there the same way I would as if I was placing the object, so it would be like this:
Vector3Int start = gridLayout.WorldToCell(oreBeingRemoved.GetStartPosition()); TakeAreaWithTile(start, oreBeingRemoved.Size, emptyTile);
When I do all this, I get an error that says
"The variable 'grid' of 'BuildingSystem' has not been assigned. You probably need to assign the grid variable of the 'BuildingSystem' script in then inspector."
The problem is that the variable is assigned. The "grid" is always there in the editor, just like that tile that I talked about was, but it says that it isn't for some reason.
Here's a screenshot:
I have tried rewriting the code so many times, I spent about 10 hours here but nothing seems to be working.
As said in the comments the lines you show do not contain the assignment of the variables or what happens to them in between. Nor does it show how your object is instantiated.
One thing that could be your problem: Prefabs can only be serialized with references to themselves or other Prefabs. References to other objects in the scene will get lost.
A fix would be a method that assigns your grid reference in the Awake method of your BuildingSystem class.
Maybe im missing something obvious but to keep it short. I have working code for a character. When you "dash" I want to leave behind an after-image type effect, by cloning the player, removing its unneeded components and then applying a shader. Issue is as soon as I instantiate the clone the original player stops functioning (cant move etc). It still has all its components and everything as normal, and the clone does get the correct components removed. But it still breaks. As soon as I remove that line, its back to normal. Any ideas?
This is the only relevant code in the script that instantiates the clone.
private void DodgeEffect()
{
GameObject _DodgeSFX = Instantiate(gameObject, transform.position, transform.rotation );
Destroy(_DodgeSFX.GetComponent<PlayerController>());
Destroy(_DodgeSFX.GetComponent<PlayerCombat>());
Destroy(_DodgeSFX.GetComponent<WarpController>());
Destroy(_DodgeSFX.GetComponent<Animator>());
}
its because you are making a copy of gameObject. while Instantiate() returns a GameObject, it also returns whatever you put into the first section of the method. instead, make a seperate gameObject than the player in the editor, and make _DodgeSFX public so you can put the copy into the slot. Then, just instantiate that seperate GameObject and you wont have to destroy the components through script(because you remove the components in the editor), saving time
Ok so from some testing I think its down to the Unity.InputSystem only allowing 1 instance of each Input to be enabled at once. When I instantiated a clone of the player, it still goes through the Enable/Awake functions before those components are destroyed, and since the Inputs on that clone were never disabled, that becomes the "main" one. If I set the main player's scripts with Inputs deactive and then active again, it all works as normal. Note that the script was still working on the main character just fine, it was only the inputs that was broken. Im still not sure why this is the case, if its a limitation of the input system, or intentional, cant seem to find documentation of this experience anywhere.
I'm currently developing a game in Unity using C# and I've run into a small problem.
I need to spawn a certain gameobjects relative to the Spawnposition and length of another game object. Now I figured that bounds.size would be the best function to use in this instance. As shown bellow I declare first the variable that uses this in my start method:
public void Start()
{
GameObject PointBar = (GameObject) Resources.Load("PointBar Horizontal");
PointBarVectorLength = PointBar.GetComponent<BoxCollider2D>().bounds.size.x;
PointBarVectorConv = Camera.main.WorldToViewportPoint(new Vector2(PointBarVectorLength, 0f));
}
However, the gameobjects in question are inactive at start's call and thus I presume don't return any value for bounds.size when called.
Does anyone know how I can access the bounds.size or equivalent of an inactive gameobject or is there something else I'm missing here?
As noted in the documentation for the Collider.bounds property, bounds "will be an empty bounding box if the collider is disabled or the game object is inactive". So your assumption was pretty much right. Since the object doesn't exist in worldspace that makes sense.
I'm not sure about the most elegant solution for your use case but two options spring to mind.
Calculate the object's spawn dimensions by accessing its transform.localScale and factoring in the scale of prospective parent objects. That could get messy but you could probably also write a helper method to make it more manageable.
Instantiate the object somewhere off screen after you load it, access its Collider.bounds property to get the information you need then move it where ever you want it or store the information for later.
There may be better solutions but that's what leaps to mind for me.
I solved the issue by using GetComponent().bounds.size.x;
instead of BoxCollider. This component can get accessed when the game object is not active.
Original question on the Unityforums here
I've been trying to get an animation to not only slow down and speed up, but also play backwards depending on user input for my Hololens-application. I am using the Mecanim system, not legacy animations.
The whole thing is supposed to happen at runtime, through dynamic user input.
I know that it's possible through scripting, as I had it working before I lost local progress and some files during some Unity-Collaborate issues. As stupid as it sounds, since then I have not been able to remember what I did different from my current approach.
Right now I'm manipulating the value Animator.speed, but that only works for values >= 0.
Any help would be greatly appreciated!
Edit: In case the link is not working or visible for anybody, here is my code:
private Animator anim;
//...
anim = gameObject.GetComponent<Animator>();
//...
public void OnManipulationUpdated(ManipulationEventData eventData)
{
if (anim.isActiveAndEnabled)
{
anim.speed = eventData.CumulativeDelta.x;
anim.Play("KA_Cover_Anim");
return;
}
//...
}
Edit2: Incorrectly marked as dupicate! The linked question does not regard a similar problem and required a different solution
Edit3: For clarification, the linked "duplicate" uses the legacy animation system which is irrelevant for my question. In Mecanim, the new animation system in Unity 5.xx, you can not access the Animations directly as shown in the selected answer. Neither is it possible to alter the animation speed as shown in in the second answer.
I'm not exactly sure what you're end goal is, but you can play animations backwards and at different speeds by using a parameter.
On the animation state, you can make it watch a parameter and multiply it against the default speed of the animation. All you need to do in code is something like
animator.setFloat("Speed",-1.0f);
Hope that helps.
I am working on Unity for a month. I am new on Unity and C#, before Unity I worked other game engines. Whatever I am working on infinite run game, I wrote random road generator. Road generator is working well but I have problem about updating road. I can update road manualy like this. How can I update it automaticly?
void Update()
{
if(Input.GetKeyDown(KeyCode.A)) UpdateRoad();
}
My UpdateRoad method adding road like this(I am using object pooling).
I want to update after Link Road, OnExitTrigger or something I dont know. How can I do it?
You would need to implement Object Pooling.
I would suggest making your Design of Objects first so you can test. Or if not use, the stock Blocks Primitive of Unity3D as your Prefabs. I hope you already know prefabs. It is a major key for making infinite runner. Actually a main core for making any kinds of game.
Prefabs is an Object File where you can Instantiate it in a location. So lets say you will generate a Flat walkable, then Generate a Pit. You would probably want to stack them together.
Now Generating them is easy. You would not like to go in an Update? Approach because most likely you're not going to update, but you're going to further stack what is going on ahead, based on your game logic.
To further Understand this, Unity3D already made a project or Fully Detailed tutorial. It maybe made in 2D but it is going to be the same, if you're going to change the Collider2D to Collider <- this is important in your case.
https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/infinite-runner
Update
You would need to create an Object, that is invisible. Meaning a Trigger.
Then on Trigger call your method UpdateRoad();
https://unity3d.com/learn/tutorials/modules/beginner/physics/colliders-as-triggers
Detailed Videos about Trigger.
If I understood your needs correctly, you could create Empty Object name it SpawnPoint, set position for Spawn Point as you need (out of the camera view) and then Instanciate random prefabs of road. Concerning On TriggerExit - it could be used to destroy "old piece of road". But to have it working properly, dont forget to set collider and rigitbody to your objects. Dont add collider2D or Rigitbody2d, add and use Box Collider and Rigitbody components