Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Dec 15, 2012 at 08:53 AM by burnpsy for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by burnpsy · Jul 25, 2012 at 09:04 AM · c#vector3runtimerespawn

Calculating a Respawn Position at Runtime

Due to a certain mechanic in my current project, I cannot have the player respawn at preset locations after dying, and instead have to calculate to the nearest safe location at runtime.

I intend to do so by checking for grounded locations that are at least X distance away from all enemies. The problem is that I have no idea how to go about calculating such a position.

What is an efficient way to determine the nearest spot that's at least a certain distance away from an array of objects, while making sure that said spot would be touching the ground so the character doesn't respawn in midair? I'd prefer answers in C#, if possible.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Seth-Bergman · Jul 25, 2012 at 09:13 AM 2
Share

I think OverlapSphere, rather than spherecast.. Otherwise that's what I would do too

avatar image Bovine · Jul 25, 2012 at 09:14 AM 0
Share

Sorry, I'll correct that, I always get those two mixed up!

avatar image burnpsy · Jul 25, 2012 at 09:40 AM 0
Share

That makes sense. I can't believe I'd forgotten about OverlapSphere.

Thanks!

3 Replies

  • Sort: 
avatar image
1
Best Answer

Answer by SheepHugger · Jul 25, 2012 at 12:16 PM

Have an array of enemies (and maybe friends) and another for possible respawn positions

 enemies : GameObject[];
 respawns : GameObject[];

 function Start()
 {
     // Find initial enemies
     enemies = GameObject.FindGameObjectsWithTag ("Enemy");
 
     // Same here, find respawns at startup
     respawns = GameObject.FindGameObjectsWithTag ("Respawn");
 }

You can also have a function for updating those two on the go. Don't call it on every frame though.

 function UpdateEnemies()
 {
     enemies = GameObject.FindGameObjectsWithTag ("Enemy");
 }
 function UpdateRespawns()
 {
     respawns = GameObject.FindGameObjectsWithTag ("Respawn");
 }

Then you simply crossreference them to each other. Go through all respawns with while() and under that go through all enemies with another while() for each respawn, or use some other solution you prefer. You can then have another array, like: availableRespawns : GameObject[];

Or availableRespawns = new GameObject();

And then if the shortest distance to closest enemy is longer than your 'safe' threshold, you add that respawn to the availableRespawns list : availableRespawns.Push(respawnYouClearedInYourScript);

Here's an older answer for one solution of how to go through multiple distances. http://answers.unity3d.com/questions/178600/check-distance-between-multiple-objects.html

I hope this helps you get started. Is there anything else?

SheepHugger out.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bovine · Jul 25, 2012 at 12:21 PM 0
Share

You wouldn't to push a list of available spawn points if you are happy with the first that matches your criteria, or you could randomly ignore a few.

Similar example on Unity's docs for FindGameObjectWithTag.

http://docs.unity3d.com/Documentation/ScriptReference/GameObject.FindGameObjectsWithTag.html

This is an alternative approach but you end up considering every enemy and every spawn potentially.

avatar image SheepHugger · Jul 25, 2012 at 12:28 PM 0
Share

Yes, I assumed that he was going to apply additional criterion to the respawns, like, if it was a game similar to Battlefield, you wouldn't want to spawn the players 5km behind the frontline - you'd rather want them spawned near the front but to a safe respawn. But you're also correct, it takes more CPU this way. Hence why it should only be done once when a player / NPC dies. That way the additional CPU usage would be hardly noticeable, unless you 'nuked' the scene and killed everyone at once.

avatar image burnpsy · Jul 25, 2012 at 12:55 PM 0
Share

So the basic idea's to have a large amount of invisible respawn points spaced around the level, use a simple "foreach" to have all of them run an OverlapSphere to check for enemies the instant the character dies, adding them to an array if no enemies overlap said sphere, and then picking the closest?

Well, in exchange for having to set a bunch of respawn points for every map (as opposed to the procedurally generated ones I intended to do), that makes the work a thousand times easier. In fact, I already had a bunch of loops set up for picking the nearest object out of an array in other scripts, so I could probably write this in two $$anonymous$$utes.

avatar image
1

Answer by Bovine · Jul 25, 2012 at 09:08 AM

You could use OverlapShere(), presuming your enemies have colliders, to find all enemies within a radius.

If your map is not flat, then you could choose a random x, z location and the ray cast down from some distance to find a ground position. If you don't find one (you don't collide with your ground collider), then you could try again.

Probably it would be best to have a list of objects that give you starting points though. Perhaps these could be check points so you choose appropriate spawns.

Placing spawns, players and enemies on separate layers will help you consider only a subset of colliders as well.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bovine · Jul 25, 2012 at 12:31 PM 0
Share

Converted to answer as @burnpsy seemed happy with that suggestion.

avatar image
1

Answer by SheepHugger · Jul 25, 2012 at 01:10 PM

You can use either the distance or OverlapSphere, I don't know which is more efficient. I would think that simply iterating through builtin arrays would be pretty fast, making simple trigonometric calculation per object. I don't exactly recall all the things that happen with OverlapSphere.

But indeed, I would assume that having set respawns per level would have higher long term quality.. considering that humans are better at choosing appropriate positions.

I personally like to use something like:

 zInt : int = 0;
 while (zInt < respawns.length)
 {
     zInt2 : int = 0;
     while (zInt2 < enemies.length)
     {
         var distance : float = 
             Vector3.Distance(respawns[zInt].transform.position, 
             enemies[zInt2].transform.position);
         if (distance < safeThreshold)
         {
             safeRespawns.Push(respawns[zInt]);
         }
         zInt2 += 1;
     }
     zInt += 1;
 }

safeRespawns could also be a builtin. Then you'd need a var called 'safeRespawnIndex : int;'. If so, then you'd make:

 safeRespawns = new GameObject[respawns.length];
 safeRespawnIndex = 0;

And everytime instead of Push() you'd do this:

 safeRespawns[safeRespawnIndex] = respawns[zInt];
 safeRespawnIndex += 1;

The benefit of this would be that safeRespawnIndex also tells you how many safe respawns were found!

Hope this is what you were after.. :/

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Moving Player After Falling Certain Distance [Beginner/C#] 1 Answer

Distribute terrain in zones 3 Answers

How to get our character controller script to make our player move? 1 Answer

overlapping object doesn't disable 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges