• 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 /
  • Help Room /
avatar image
0
Question by Zodiarc · May 31, 2016 at 04:19 PM · movementturn-basedarea

Movement area outline

Hi

I´m working on a turn based strategy game. Right now I display the area a character can move using projectors (for terrain adaptability of the tiles). Every tile is an empty with a projector attached and every projector within the movement area is being turned on to display a single tile (see screenshot). You can imagine that this is really unperformant (I read something about that a mesh has to be rendered again for every projector it receives).

I wanted to just make an outline (by using a line renderer for example) of the area where a character can move (similar to XCOM 2) have no idea how to do that. Can anyone help? The area is stored within an array of transforms.

alt text

If it somehow helps here's the code which generates the area:

 using UnityEngine;
 using System.Collections;
 
 namespace Grid
 {
     [System.Serializable]
     public class AreaBuilder: MonoBehaviour, AreaBuilderInterface
     {
         public Grid grid;
 
         public ArrayList traversed;
 
         public LayerMask layerMask;
 
         public void buildArea(Vector3 start, int min, int max)
         {
             GameObject startTile = this.grid.getTileAtPosition(start.x, start.z);
             ArrayList openList = new ArrayList();
             openList.Add(startTile);
             this.traversed = new ArrayList();
             ArrayList withinMinArea = new ArrayList();
             this.traverseTiles(openList, withinMinArea, min, max, true);
             if(this.traversed != null)
             {
                 for (int i = 0; i < this.traversed.Count; i++)
                 {
                     GameObject currentCell = (GameObject)this.traversed[i];
                     currentCell.GetComponent<Projector>().enabled = true;
                 }
             }
         }
 
         private void traverseTiles(ArrayList openList, ArrayList withinMinArea, int min, int max, bool useRaycast)
         {
             if(max == 0)
             {
                 return;
             } else
             {
                 ArrayList tempOpenList = new ArrayList();
                 for (int i = 0; i < openList.Count; i++)
                 {
                     GameObject currentTile = (GameObject) openList[i];
                     Tile.AbstractTileController projectorTile = currentTile.GetComponent<Tile.AbstractTileController>();
                     for (int j = 0; j < projectorTile.neighbors.Count; j++)
                     {
                         GameObject currentNeighbor = (GameObject) projectorTile.neighbors[j];
                         if (currentNeighbor == null)
                         {
                             continue;
                         }
                         if (useRaycast)
                         {
                             RaycastHit hit;
 
                             Vector3 currentCorrectedPosition = new Vector3(currentTile.transform.position.x,
                                                                             currentTile.transform.position.y + 3f, currentTile.transform.position.z);
                             Vector3 neighborCorrectedPosition = new Vector3(currentNeighbor.transform.position.x,
                                                                                 currentTile.transform.position.y + 3f, currentNeighbor.transform.position.z);
                             Debug.DrawLine(currentCorrectedPosition, neighborCorrectedPosition, Color.red, 60);
 
                             Vector3 checkDirection = neighborCorrectedPosition - currentCorrectedPosition;
                             int ignoreLayer = ~(1 << 9);
                             Ray ray = new Ray();
                             ray.origin = currentCorrectedPosition;
                             ray.direction = checkDirection;
                             if (!Physics.Raycast(ray, out hit, Vector3.Distance(currentCorrectedPosition, neighborCorrectedPosition), this.layerMask))
                             {   
                                 if (!this.traversed.Contains(currentNeighbor))
                                 {
                                     this.traversed.Add(currentNeighbor);
                                 }
                                 if (!withinMinArea.Contains(currentNeighbor) && min < max)
                                 {
                                     withinMinArea.Add(currentNeighbor);
                                 }
                                 if (!tempOpenList.Contains(currentNeighbor))
                                 {
                                     tempOpenList.Add(currentNeighbor);
                                 }
                             }
                         } 
                     }
                 }
                 max--;
                 this.traverseTiles(tempOpenList, withinMinArea, min, max, useRaycast);
             }
         }
 
         public void dropArea()
         {
             foreach(GameObject tile in this.traversed)
             {
                 tile.GetComponent<Projector>().enabled = false;
             }
         }
     }
 }

scrnshot.jpg (471.5 kB)
Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by ricke44654 · Jun 01, 2016 at 03:54 AM

Is your array of transforms a series of point locations that define the perimeter of the area? If so, then it seems like you need a script that would loop through your transform array and call the LineRenderer.SetPosition method similar to the following:

 lineRenderer.SetPosition(0, new Vector3(Position1.transform.position.x,Position1.transform.position.y,Position1.transform.position.z));
 lineRenderer.SetPosition(1, new Vector3(Position2.transform.position.x,Position2.transform.position.y,Position2.transform.position.z));

So you'd probably end up with code like the following:

 int posCount = 0;
 foreach (var curTransform in transformArray) {
     lineRenderer.SetPosition(posCount, new Vector3(curTransform.position.x, curTransform.position.y, curTransform.position.z));
     posCount++;
 }

According to the Unity docs, LineRenderer should be the only renderer on a game object, so you might need a child game object if your game object for your area has other responsibilities. Hope this helps.

Comment
Add comment · Show 4 · 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 Zodiarc · Jun 01, 2016 at 06:30 AM 0
Share

I guess I didn't specify it enough. The array (or ArrayList in that case) containing the transforms contains every single tile the player can move to (it's simpler to check if the mouse is hovering over a valid position with movementArea.Contains(position)), not only the area edges. $$anonymous$$y main problem is how to detect those edges. I mean I could make an extra array and fill it every time i reach the maximum range or if not all tile neighbours are accessible but how do I guarantee the order of the tiles so that I get a nice straight outline and not a wild amalgamation of lines. Sure I could sort them but by what?

avatar image ricke44654 · Jun 01, 2016 at 01:38 PM 0
Share

Ah, so it's the whole area... got it. :) One thought would be to go through the transforms array and find the transforms with the smallest / largest values on the x and z axes. That should be the tips of your area, correct? Then you'd loop through that list to use those points for rendering your lines.

avatar image Zodiarc ricke44654 · Jun 02, 2016 at 11:24 AM 0
Share

$$anonymous$$ind of. But the area also adapts if there are obstacles within it. I think I got an idea. I'll test it on weekend and describe it if it worked.

avatar image Zodiarc · Jun 13, 2016 at 12:01 PM 0
Share

So.. I made some progress:

alt text

But It's still not entirely what I want. I'll post the current algorithm later for other people with that problem. It's probably not the best approach but it's fast enough for me and it works (until I find a case when it won't wort xD) the area looks cut off on the left and down side because it hit the border of the grid.

whatsapp-image-20160612.jpg (149.3 kB)
avatar image
0

Answer by echolink · Mar 15, 2020 at 06:20 AM

hi @Zodiarc
did you successfully get the XCOM look for your movement area outline? i'm want to learn to make it too

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

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

68 People are following this question.

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

Related Questions

turn-based movement 0 Answers

Moving object inside another object's area 1 Answer

Turn Based Movement - Using Movement Points 0 Answers

Roll-A-Ball Rolling Sound 5 Answers

2D Platformer Character Acts Weird When Collide Side of a Platform 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges