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 /
avatar image
1
Question by ellioth · Nov 16, 2014 at 04:26 AM · grid based gamegridmove2d-game

Asymmetricly placed, data containing, predefined movement locations for a 2d, top down turn based tactical game that takes place on a topographic map

Please forgive any misuse of terms, I am very new to game making in general. I am trying to make a 2d tactical game that takes place on a topographic map where I create the move spaces based off of terrain features. This means that each move space will have a different shape and I will also have to set which spaces each movement space has a LOS to.

Could anyone help point me in a direction for how to accomplish this or how to better pose this question if I am being unclear?

Thank you so much in advance for any help.

Edit: I updated the title to what I believe conveys the concept much better than the previous one.

Comment
Add comment · Show 5
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 Cherno · Nov 16, 2014 at 01:12 PM 0
Share

Please post a picture explaining your concept.

avatar image ellioth · Nov 16, 2014 at 02:01 PM 0
Share

Please forgive the poor drawing: https://docs.google.com/file/d/0B1G5FQvunF5uNmtleF9YaEpTckk/edit

The idea is that I create predeter$$anonymous$$ed position points that conform to line-of-sight blocking terrain features. This is similar to a grid move system but different in that the move spots are not aligned with the x,z axes, rather along natural topographic formations.

$$anonymous$$y thinking is that for a 2D top-down tactical infantry combat game this will make it easier to deter$$anonymous$$e LOS because I will tell each position which other positions it can see. Each position will have ratings for cover, concealment, and elevation that I will input from studying the satellite imagery. This will hopefully make it easier for creating an AI that will seek out preferred ratings for cover, concealment, and LOS when when the situation becomes less desirable for the unit. These points will also be nodes for path-finding. Again, please forgive me if any of this doesn't make sense given I may be misusing ter$$anonymous$$ology as I am new to this.

Thank you so much for responding and if you could help in any way please do not hesitate to ask more clarifying questions.

avatar image Scribe · Nov 16, 2014 at 02:04 PM 0
Share

have you already got height information for the map etc. What have you achieved so far?

avatar image ellioth · Nov 16, 2014 at 02:12 PM 0
Share

I have the World Composer asset addon and have learned how to make 3d real world models of terrain. I also have a lot of experience with topographic maps and I was planning on just using the contour lines to see elevation and inputting it by hand unless there is an easier way to do it. So far this project is still very early and I only recently began learning Unity but I am very serious about this project and any help and more questions are greatly appreciated.

avatar image ellioth · Nov 16, 2014 at 02:15 PM 0
Share

For me so far, gathering the data is the easy part. I am just unsure where to go and how to proceed to implement my ideas. I am spending as much time as I can watching tutorials and learning Unity, but again I am very new to this.

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Scribe · Nov 16, 2014 at 10:46 PM

Coding your own line of sight check is NOT easy, if you have a height map then I would suggest creating the terrain or mesh that goes with it and then using the built in raycast functions to check for each 'grid space' which other grid spaces it can see.

you can do that quite simply by having a few embedded for loops:

 Vector3[,] gridSpace;
 
 //For each grid space
 for(int z = 0; z < depth; z++){
 for(int x = 0; x < width; x++){
     Vector3 parentSpace = gridSpace[x, z];
 
     //Check all grid spaces
     for(int zi = 0; zi < depth; zi++){
     for(int xi = 0; xi < width; xi++){
         Vector3 childSpace = gridSpace[xi, zi];
     
         // shoot a ray from your gridSpace[x, z] to gridSpace[xi, zi] and see if it hits anything on the way, if not, then this 'childSpace' grid space if visible from the 'parentSpace'
         // save that information somewhere!
     }
     }
 }
 }


Because I had lots of work to do I decided to procrastinate and see if I could write my own line of sightcode so here is a basic (and bad) implementation of how you could do it from scratch using some heightmap data:

 using UnityEngine;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 
 public class heightmap : MonoBehaviour {
     float[,] heights;
     HeightMap hMap;
     public int xSize = 12;
     public int zSize = 3;
     
     void Start(){
         heights = new float[xSize,zSize];
         for(int z = 0; z < zSize; z++){
             for(int x = 0; x < xSize; x++){
                 heights[x, z] = UnityEngine.Random.Range(0f, 1f);
             }
         }
         hMap = new HeightMap(heights, Vector3.zero, 1, 0.5f);
     }
 }
 
 public class HeightMap {
     HeightPoint[,] hPoints;
     float pointSpacing;
     Vector3 origin;
     int width;
     int depth;
     float viewUpHeight;
     
     public HeightMap(float[,] h, Vector3 o, float space, float viewUH){
         pointSpacing = space;
         origin = o;
         width = h.GetLength(0);
         depth = h.GetLength(1);
         viewUpHeight = viewUH;
         hPoints = new HeightPoint[width, depth];
         for(int z = 0; z < depth; z++){
             for(int x = 0; x < width; x++){
                 hPoints[x, z] = new HeightPoint(x, z, new Vector3(origin.x+x*pointSpacing, origin.y+h[x, z], origin.z+z*pointSpacing), this);
             }
         }
         CalcLineOfSight();
         CreateMap();
     }
     
     public void CreateMap(){
         for(int z = 0; z < depth; z++){
             for(int x = 0; x < width; x++){
                 GameObject o = GameObject.CreatePrimitive(PrimitiveType.Plane);
                 o.transform.position = hPoints[x, z].pos;
                 o.transform.localScale = Vector3.one*pointSpacing/10;
                 o.name = x + ", " + z;
             }
         }
     }
     
     public void CalcLineOfSight(){
         HeightPoint p;
         for(int z = 0; z < depth; z++){
             for(int x = 0; x < width; x++){
                 List<Point> haveChecked = new List<Point>();
                 p = hPoints[x, z];
                 p.Add(p);
                 for(int zi = 0; zi < depth; zi++){
                     for(int xi = 0; xi < width; xi++){
                         if(zi == z && xi == x){
                             continue;
                         }
                         //check indexes on line to target
                         List<Point> points = FindIntersectedIndexes(x, z, xi, zi);
                         
                         //check visibility through each index on line
                         float maxViewGrad = viewUpHeight;
                         float minViewGrad = Mathf.NegativeInfinity;
                         float grad = 0;
                         for(int i = 0; i < points.Count; i++){
                             if(points[i].x == x && points[i].y == z){
                                 continue;
                             }
                             grad = (hPoints[points[i].x, points[i].y].height - p.height)/(new Vector2(x-points[i].x, z-points[i].y).magnitude);
                             minViewGrad = Mathf.Max(minViewGrad, grad);
                             if(minViewGrad > maxViewGrad){
                                 break;
                             }
                             if(grad > maxViewGrad){
                                 break;
                             }
                             if(grad < minViewGrad){
                                 continue;
                             }
                             if(p.visiblePoints.Contains(hPoints[points[i].x, points[i].y])){
                                 continue;
                             }
                             p.Add(hPoints[points[i].x, points[i].y]);
                         }
                     }
                 }
             }
         }
     }
     
     List<Point> FindIntersectedIndexes(int y1, int x1, int y2, int x2){ 
         //Implements a variation on Bresenham's line algorithm
         List<Point> points = new List<Point>();
         int i;
         int ystep;
         int xstep;
         int error;
         int errorprev;
         int y = y1;
         int x = x1;
         int ddy, ddx;
         int dx = x2 - x1;
         int dy = y2 - y1;
         points.Add(new Point(y1, x1));
         if (dy < 0){
             ystep = -1;
             dy = -dy;
         }else{
             ystep = 1;
         }
         if (dx < 0){
             xstep = -1;
             dx = -dx;
         }else{
             xstep = 1;
         }
         ddy = 2 * dy;
         ddx = 2 * dx;
         if(ddx >= ddy){
             errorprev = error = dx;
             for (i=0 ; i < dx ; i++){
                 x += xstep;
                 error += ddy;
                 if (error > ddx){
                     y += ystep;
                     error -= ddx;
                     if (error + errorprev < ddx){ 
                         points.Add(new Point(y-ystep, x));
                     }else if (error + errorprev > ddx){ 
                         points.Add(new Point(y, x-xstep));
                     }else{
                         points.Add(new Point(y-ystep, x));
                         points.Add(new Point(y, x-xstep));
                     }
                 }
                 points.Add(new Point(y, x));
                 errorprev = error; 
             }
         }else{
             errorprev = error = dy; 
             for (i=0 ; i < dy ; i++){ 
                 y += ystep; 
                 error += ddx; 
                 if (error > ddy){ 
                     x += xstep; 
                     error -= ddy; 
                     if (error + errorprev < ddy){
                         points.Add(new Point(y, x-xstep));
                     }else if (error + errorprev > ddy){
                         points.Add(new Point(y-ystep, x));
                     }else{
                         points.Add(new Point(y, x-xstep));
                         points.Add(new Point(y-ystep, x));
                     }
                 }
                 points.Add(new Point(y, x));
                 errorprev = error;
             }
         }
         return points;
     }
 }
 
 public class HeightPoint{
     int x;
     int y;
     float h;
     public Vector3 pos;
     public List<HeightPoint> visiblePoints = new List<HeightPoint>();
     HeightMap hMap;
     
     public HeightPoint(int xi, int yi, Vector3 p, HeightMap container){
         pos = p;
         h = p.y;
         hMap = container;
         x = xi;
         y = yi;
     }
     public HeightPoint(int xi, int yi, Vector2 p, float he, HeightMap container){
         pos = new Vector3(p.x, h, p.y);
         h = he;
         hMap = container;
         x = xi;
         y = yi;
     }
     
     public void Add(HeightPoint hP){
         visiblePoints.Add(hP);
     }
     
     public void DebugVisible(){
         foreach(HeightPoint a in visiblePoints){
             Debug.Log(a.x + ", " + a.y);
         }
     }
     
     public float height{
         get { return h; }
         set { h = value; }
     }
 }
 
 public class Point{
     public int x;
     public int y;
     
     public Point(int xi, int yi){
         x = xi;
         y = yi;
     }
 }

The each 'HeightPoint' instance should contain a list of the HeightPoint's that it can 'see'

I would not advise anyone to use that code over the former alternative I suggested, but it was an interesting challenge to get working, so enjoy that headache!

Scribe

Comment
Add comment · Show 2 · 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 ellioth · Nov 17, 2014 at 12:23 AM 0
Share

Wow, thank you so much! This is great! How do I place the height points? Could I do it by creating empty objects? Thank you again!

avatar image Scribe · Nov 17, 2014 at 11:35 AM 0
Share

You could do, at the moment it is just randomized at line 16, normally you would get this data from your map, but you said 'For me so far, gathering the data is the easy part' so I'll leave that up to you or you could post a new question, this is just demonstrating how to check line of sight once you have your data in a 2D float array :)

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.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Player movement on a grid? 1 Answer

How can I Stop grid based movement on One or more access? 0 Answers

Road placement and road removement during run mode 0 Answers

Grid-based movement with auto-move 1 Answer

Collision with grid based movement 0 Answers


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