Detect collision in circle and destroy other car unity - unity3d

I am working on a car multiplayer game and i want if the player 1 and player2 is in circle and the other players (player 3,4,5) are outside the circle then the outside players (player 3,4,5) destroy and the circle players (player 1,2) won.. I dont understand hows it possible
I use ontrigger but i dont understand how can I apply this

Well with the limited knowledge of your project, the best advice I can give is have a collider for that circle, make it a trigger, and make a Collision script for it where you have the following method
void OnTriggerEnter (Collider other)
{
if (other.gameObject.name(or tag) == "Whatever the tag or name you want")
{
// check here for some field or identifier for the specific instance
// of the object to see which player entered the circle
carMasterScript.DestroyEverythingExcept(other);
}
}
Once you replace the vague things here with what you have in your scripts, and possibly make some Master script so you can have a single instance that can reach and access every car/player instance, this should trigger when another trigger object(make the cars trigger rigidbodies or kinematic bodies as well) and check to see if the thing that collided is a car, then protects that instance of the car while destroying every other one

Related

Enemy Taking Multiple Damage - Swift, Xcode 8.2.1

I'm in the process of making a space invaders style game, and would like to make it so that an enemy must be hit three times before exploding.
The tutorial I am using only shows how to make enemies explode after only one hit. It uses a function called didBegin(_ contact: SKPhysicsContact)
https://www.youtube.com/watch?v=F0kcw6eryJs&t=617s
Now, this function, from my understanding, evaluates each instance of contact, assigns two bodies two distinct roles, and then decides what to do with each body. I assume to have an enemy take three hits, a variable containing their remaining health would be used. Then, with each instance of contact, the variable would decrease by one, until if it is zero, the enemy is removed.
However, there is a deep problem in this. SincedidBegin(_ contact: SKPhysicsContact) evaluates only one instance of contact, it has no knowledge of other previous instances of contact. Essentially, when an enemy gets hit, there is no way to know if the enemy was hit before, has not been hit at all, or has been hit too many times. If there was only one enemy, then I could use one variable to keep track of its health. This is not the case, though, as there are multiple enemies on screen at once, and every time contact is made, there is no way to know if the previous hit was on this enemy, or another enemy.
If there is one enemy on screen, it is simple because every time contact is made it would have to be that one enemy. But if there are multiple entities on screen, then there is no way to know which enemy a contact applies to.
I believe this would require some sort of identification for each instance of an enemy, though I an unsure of how to do this. For those of you reading, I have many thanks for dropping in, and I am very grateful if you can help.
There is no need to keep separate dictionaries to track states of a sprite
Every SKNode has userData, and you can track an enemies life with it
Example:
let invader = SKSpriteNode(imageNamed:"invader")
invader.userData = ["health":3]
...
func didBeginContact(...)
{
...
//when a contact happens
contact.body_.node.userData["health"] -= 1
...
}
Now keep in mind, 1 bullet can hit 1 enemy two times. You do not want to trigger 2 losses of life here, so you are going to need to have a temporary variable (which you can also save in userData) that lets you know if a particular bullet has already made contact with an invader.
You are absolutely right, you somehow need to track your enemies and their health on your own. There are probably a bunch of ways to do it but here is one way of achieving what your aiming for:
Use a dictionary of enemies with their health. Every enemy will be given an id of some sort to identify them. The health could be represented as an Int. This dictionary can also be used to easily tell how many enemies are still around.
var enemyHealth = [String:Int]()
Nodes have a name property that you can set any string value to. This is how you'll be able to identify your nodes. When creating an enemy, you'll create an id (for instance generating a random number), set the name of the node as the id and add the enemy to the enemyHealth dictionary with a default health value.
let enemyNode = SKSpriteNode(color: UIColor.white, size: CGSize.zero)
let enemyId = "\(arc4random())"
enemyNode.name = enemyId
enemyHealth[enemyId] = 10
...
In didBegin(_ contact: SKPhysicsContact) you can access the involved nodes in the collision using the contact parameter of the function (contact.bodyA.node or contact.bodyB.node). By comparing the names of the nodes with the keys in enemyHealth, you can figure out which collision body was the enemy and what health it has.
let enemy:SKSpriteNode
if enemyHealth.keys.contains(contact.bodyA.node?.name ?? "") {
enemy = contact.bodyA.node as! SKSpriteNode
} else if enemyHealth.keys.contains(contact.bodyB.node?.name ?? "") {
enemy = contact.bodyB.node as! SKSpriteNode
} else {
return //none of the collision partners are an enemy
}
let health = enemyHealth[enemy.name!]!
...
Now you can do whatever you want with the enemy. When the enemy is killed/removed then also remove it from the enemyHealth dictionary.

unity jumping collisions - how enemy is damaged

I am making a platformer in Unity using unityscript.
I have a Player parent object with a character controller and various child objects. I have a similar enemy with a box collider. I'm struggling to differentiate between the collision happening when the player walks into the enemy and when the the player jumps and collides with it from above.
I've tried tagging the child objects but they don't have colliders. If I add colliders to the child objects, it messes up my character movement. I've also tried to test the position of the player:
if(col.transform.position.y >= transform.position.y){ killThyself(); }
But this doesn't work either - should I add the height of the enemy? If so how do I do that?
Any suggestions happily received.
Mmmm, I would use a boolean variable. Make it true when you press the jump button, and false once the jump has finished (when the player touches the floor). Declare the boolean as a public variable.
After that, in the OnCollision method, check the variable value.
I recommend you to read this to understand how to do that:
http://docs.unity3d.com/Documentation/ScriptReference/index.Accessing_Other_Game_Objects.html
Well, in your case I would assign the "otherScript" (the player script) doing this in the enemy control script:
var player : GameObject;
var playerScript: PlayerScript;
//I'm assuming "PlayerScript" is the name of the control script of your player,
//where you defined the "jump" variable.
function Start()
{
player = GameObject.FindGameObjectWithTag("Player");
//You also can use GameObject.Find("PlayerName")
playerScript = player.GetComponent(PlayerScript);
//Get the script from the player
}
function OnCollisionEnter(col : Collision)
{
if (playerScript.jump == true)
{
killThyself();
}
}
I'm finding the player on the function Start, to find it only ONCE, in the level load. Now, I assign the player script into a variable, so, when the player hit the enemy, this enemy will check if the player is jumping using his script. Remember to declare this variable as a public variable or this won't work.
Please comment if you have any problem using this method =)
I would use a second collider at the upper part of the enemy let's called it headCollider. Set isTrigger = true and maybe use a special physics material. If this headCollider is the first one to get triggered you know that the player chararacter is jumping on the enemy or is falling on it from above.
In OnTriggerEnter (Collider other) you can prepare some status variables (and maybe a timer for resetting the status). Also the current jump status like in V_Programmer's answer suggested should be useful for evaluation.
As Unity does not allow you to attach 2 colliders of the same kind, you have to use box and sphere or create an empty child and use that one.

Collision detection between two character controllers

I am new to Unity and scripting. I have two players and both are using a character controller. I have done this thing
I have used onControllerColliderHit function.
I have print the name like this gameobj.name.
It will show the name of the object that it hit
But the problem is it passes through it. I want that it's not able to pass through it and it will behave just like rigid bodies have. Like there must be effect of force through which second player hit it.
Check the doc. CharacterController as is has no RigidBody attached:
The Character Controller is mainly used for third-person or
first-person player control that does not make use of Rigidbody
physics.
Basically CharacterController is only a Collisor designed for preventing compenetration between the character and objects in the scene, but doesn't work as you expect when the collision occurs between 2 CharacterControllers.
Particularly:
The Controller does not react to forces on its own and it does not
automatically push Rigidbodies away.
Like shown in OnControllerColliderHit documentation you can manually handle the collision when this occurs. For example you can push away from each other the character controller object when they collide since you have the move direction:
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
transform.Translate (-pushDir * offset);

unity moving to another scene with current scene being paused

I'm making a turn-based battle game in Unity3D and I have 2 scenes (a town scene and a battle scene). Whenever the character meets a monster, the game jumps to the battle scene where the character does battle and go back to the town scene after defeating or losing.
The problem is how to return to the town scene with the same state as when the character enters the battle scene (character position, statuses, etc.)
if I use
Application.LoadLevel('battlescene');
then
Application.loadLevel('townScene');
then the townscene will start from the first time. How to make the townscene continue from where we left off?
There are two ways that I think you can accomplish this. It all depends on your target platform and how important resources are but here we go:
1) If resources aren't an issue
You could put all your normal scene and battle scene objects in one scene.
Create two empty game objects (One for Town Scene objects and the other for Battle Scene Objects). You can then either have two versions
of your game character(s) or one. Then write a script that simply
switches the camera(s) from the town scene to the battle scene when
a battle is triggered and back to the town scene when the battle is
over.
If you have one version of each character you could simply add a script that changes the behaviour of your game character controller
to/from battle mode and normal/town mode.
If you have two versions of each character then you would simply need to write the appropriate character controller scripts and
activate/deactivate the game characters according to which one you are
using. This is how games like Final Fantasy 7,8,9 achieved the same
effect. There were two versions of the game characters: one for battle mode and the other for normal mode.
2) If resources ARE an issue
(and I think a more efficient way)
You could use the Application.LoadLevelAdditive function. This function allows you to load a different scene and rather than destroy everything in the current scene, it takes the new scene and all it's objects and adds them to the current scene.
So basically you can use it something like this:
Create a separate battlescene and within your scene, create an empty game object to hold every object in your scene.
In your noraml scene do the same.
When you need to go to battle mode use:
Application.LoadLevelAdditive ('battlescene');
And when/if you want to unload your battlescene after that you can do so by simply writing code to destroy the battlescene game object
since it contains everything from your battle scene.
As with the first method you can decide whether you want to have two different versions of your characters or not. One of the pros of having two versions is that if you want to save time by not going into detail with you game models (especially if your game is really big) you can have save processing power by using scaled down models for the town scene and using polished more detailed models for the battle scene, assuming your battle scene is a small stage representing the place where your characters are fighting. Think final fantasy VII. Just something to consider.
I hope that helps. I've written it all in a rush but lemme know if anything needs clearing up.
You can do it by script in c#
void onYourFunction()
{
Time.timeScale = 0; //pauses the current scene
Application.LoadLevelAdditive("YourNextScene"); //loads your desired other scene
}
And when you want to activate your game back you can use Time.timeScale = 1;
I know this is an old post, but there is one more method that can be used. This would be to save the state of the scene. This comes in handy when you don't expect users to have the resources for loading 2 scenes with the Application.LoadLevelAdditive. That method potentially can use twice the resources.
When you save the state (save all information that can change to a file or DB) you can then load the level at a later time and not have it sitting in memory. You could also use this to save your game.
I know it is on old post. But I have found another, very easy solution for my case. Just deactivating all GameObjects from one scene while the other is active and then reactivate it, as soon I go back to the root scene:
[Button]
public void UnPauseScene()
{
EndlessSceneCamera.gameObject.SetActive(true);
Time.timeScale = 1;
levelStatus = LevelStatus.Running;
foreach (var go in activeGameObjectsBeforeScenePaused)
{
go.SetActive(true);
}
}
[Button]
public void PauseScene()
{
//EndlessSceneCamera.gameObject.SetActive(false);
levelStatus = LevelStatus.Pause;
Time.timeScale = 0;
var allGameObjects = FindObjectsOfType<GameObject>().ToList();
activeGameObjectsBeforeScenePaused = allGameObjects.Where(x => isActiveAndEnabled).ToList();
foreach (var go in activeGameObjectsBeforeScenePaused)
{
go.SetActive(false);
}
}

Creating pointer Attributes in cocos2d iPhone

I am working on a game. There are balls that fall from the top of the screen, and the player has to catch them, as the are caught they stack ontop of one another. I have a method that creates each new ball and adds it to an Array that i use to move the sprites. Problem is that the after they collide I need them to stop moving, since the array is called on to move them they all move. And if i try to make them stop they all stop. So I was hoping to create a pointer attribute if ther is such a think, for example "sprite.position" I need a new attribute that i can check like a boolean. I was hoping to create a attribute like sprite.hasCollided and if it returns YES then the ball should no longer move. Is this possible or is there a better way to do it?
Thanks
Tanner
I would suggest you create a ball object. And add the boolean as as part of the object.
CCNodes (and, by inheritence, CCSprites) have a userData property, which is a void*. You can use this to relate a custom object to a cocos2d object. Keep in mind if you use the userData option, you will, in most cases, need to allocate any memory when you create/assign the sprite, and release it when you are done.
int* myInt = (int*)malloc(sizeof(int));
*myInt = 0;
sprite.userData = myInt;
//some time later, when you are done with the sprite
free(sprite.userData);
As an improvement on the userData property, you can do what xuanweng suggests and create a ball object containing various game-related properties for the balls, and assign an instance of this to each of your ball CCSprites using the method above.