Search Unity

Grid Based First Person Movement (Wizardry, EoB, CoH style) C# Script

Discussion in 'Getting Started' started by DrakkathSenpai, Jun 13, 2017.

  1. DrakkathSenpai

    DrakkathSenpai

    Joined:
    Jun 13, 2017
    Posts:
    3
    I see this question asked lots, and I asked it myself when I was first starting to get my hands dirty in Unity. Now that I know a bit more than I did a month ago, I've finally created a workable solution and thought it'd share it in hopes that it helps someone else.

    It's probably sloppy, there are probably more efficient ways to code it, and it's not very well commented but here it is in case you find it useful. Attach this script to your MainCamera.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerCamera : MonoBehaviour
    6. {
    7.     [Tooltip("The 'animation' loop for movement to reach your desired movement units. The defaults move 1 Unity unit. Adjust this to suit your level design.")]
    8.     public float fMovementIncrement = 0.05f;
    9.     [Tooltip("The 'animation' loop for movement to reach your desired movement units. The defaults move 1 Unity unit. Adjust this to suit your level design.")]
    10.     public float iMovementInterval = 20;
    11.     [Tooltip("Locked Y position of the camera, adjust to suit your level design.")]
    12.     public float fYLockPosition = 0f;
    13.     [Tooltip("Public only for debugging, these values are overridden at runtime.")]
    14.     public bool bMoving = false;
    15.     [Tooltip("Public only for debugging, these values are overridden at runtime.")]
    16.     public bool bRotating = false;
    17.     [Tooltip("fRotateIncrement * iRotateInterval must equal 90 for full grid movement. For faster rotating, lower the interval and raise the increment.")]
    18.     public float fRotateIncrement = 4.5f;
    19.     [Tooltip("fRotateIncrement * iRotateInterval must equal 90 for full grid movement. For faster rotating, lower the interval and raise the increment.")]
    20.     public int iRotateInterval = 20;
    21.     [Tooltip("The WaitForSeconds value returned for each return yeild of the Coroutines.")]
    22.     public float fWaitForSecondsInterval = 0.01f;
    23.  
    24.     public enum Compass { N, S, E, W }
    25.     Compass currentCompass = Compass.N;
    26.  
    27.     void Start()
    28.     {
    29.         bMoving = false;
    30.         bRotating = false;
    31.     }
    32.  
    33.     void Update()
    34.     {
    35.  
    36.         if (!bRotating && !bMoving)
    37.         {
    38.             transform.position = new Vector3(Mathf.Round(transform.position.x), fYLockPosition, Mathf.Round(transform.position.z));
    39.         }
    40.         if (Input.GetKey(KeyCode.W))
    41.         {
    42.             if (!bRotating && !bMoving)
    43.             {
    44.                 StartCoroutine(StepForward());
    45.             }
    46.         }
    47.         if (Input.GetKey(KeyCode.S))
    48.         {
    49.             if (!bRotating && !bMoving)
    50.             {
    51.                 StartCoroutine(StepBackward());
    52.             }
    53.         }
    54.         if (Input.GetKey(KeyCode.Q))
    55.         {
    56.             if (!bRotating && !bMoving)
    57.             {
    58.                 StartCoroutine(StepLeft());
    59.             }
    60.         }
    61.         if (Input.GetKey(KeyCode.E))
    62.         {
    63.             if (!bRotating && !bMoving)
    64.             {
    65.                 StartCoroutine(StepRight());
    66.             }
    67.         }
    68.         if (Input.GetKey(KeyCode.D))
    69.         {
    70.             if (!bRotating && !bMoving)
    71.             {
    72.                 StartCoroutine(RotateRight());
    73.             }
    74.         }
    75.  
    76.         if (Input.GetKey(KeyCode.A))
    77.         {
    78.             if (!bRotating && !bMoving)
    79.             {
    80.                 StartCoroutine(RotateLeft());
    81.             }
    82.         }
    83.  
    84.     }
    85.  
    86.     IEnumerator StepForward()
    87.     {
    88.         Vector3 newpos;
    89.         if (currentCompass == Compass.N)
    90.         {
    91.             bMoving = true;
    92.             for (int g = 0; g < iMovementInterval; g++)
    93.             {
    94.                 newpos = new Vector3(0, 0, .05f);
    95.                 transform.position += newpos;
    96.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    97.             }
    98.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    99.             bMoving = false;
    100.         }
    101.         if (currentCompass == Compass.S)
    102.         {
    103.             bMoving = true;
    104.             for (int g = 0; g < iMovementInterval; g++)
    105.             {
    106.                 newpos = new Vector3(0, 0, -fMovementIncrement);
    107.                 transform.position += newpos;
    108.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    109.             }
    110.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    111.             bMoving = false;
    112.         }
    113.         if (currentCompass == Compass.E)
    114.         {
    115.             bMoving = true;
    116.             for (int g = 0; g < iMovementInterval; g++)
    117.             {
    118.                 newpos = new Vector3(fMovementIncrement, 0, 0);
    119.                 transform.position += newpos;
    120.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    121.             }
    122.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    123.             bMoving = false;
    124.         }
    125.         if (currentCompass == Compass.W)
    126.         {
    127.             bMoving = true;
    128.             for (int g = 0; g < iMovementInterval; g++)
    129.             {
    130.                 newpos = new Vector3(-fMovementIncrement, 0, 0);
    131.                 transform.position += newpos;
    132.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    133.             }
    134.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    135.             bMoving = false;
    136.         }
    137.  
    138.  
    139.     }
    140.  
    141.     IEnumerator StepBackward()
    142.     {
    143.         Vector3 newpos;
    144.         if (currentCompass == Compass.N)
    145.         {
    146.             bMoving = true;
    147.             for (int g = 0; g < iMovementInterval; g++)
    148.             {
    149.                 newpos = new Vector3(0, 0, -.05f);
    150.                 transform.position += newpos;
    151.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    152.             }
    153.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    154.             bMoving = false;
    155.         }
    156.         if (currentCompass == Compass.S)
    157.         {
    158.             bMoving = true;
    159.             for (int g = 0; g < iMovementInterval; g++)
    160.             {
    161.                 newpos = new Vector3(0, 0, fMovementIncrement);
    162.                 transform.position += newpos;
    163.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    164.             }
    165.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    166.             bMoving = false;
    167.         }
    168.         if (currentCompass == Compass.E)
    169.         {
    170.             bMoving = true;
    171.             for (int g = 0; g < iMovementInterval; g++)
    172.             {
    173.                 newpos = new Vector3(-fMovementIncrement, 0, 0);
    174.                 transform.position += newpos;
    175.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    176.             }
    177.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    178.             bMoving = false;
    179.         }
    180.         if (currentCompass == Compass.W)
    181.         {
    182.             bMoving = true;
    183.             for (int g = 0; g < iMovementInterval; g++)
    184.             {
    185.                 newpos = new Vector3(fMovementIncrement, 0, 0);
    186.                 transform.position += newpos;
    187.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    188.             }
    189.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    190.             bMoving = false;
    191.         }
    192.  
    193.     }
    194.  
    195.     IEnumerator StepLeft()
    196.     {
    197.         Vector3 newpos;
    198.         if (currentCompass == Compass.N)
    199.         {
    200.             bMoving = true;
    201.             for (int g = 0; g < iMovementInterval; g++)
    202.             {
    203.                 newpos = new Vector3(-fMovementIncrement, 0, 0);
    204.                 transform.position += newpos;
    205.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    206.             }
    207.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    208.             bMoving = false;
    209.         }
    210.         if (currentCompass == Compass.S)
    211.         {
    212.             bMoving = true;
    213.             for (int g = 0; g < iMovementInterval; g++)
    214.             {
    215.                 newpos = new Vector3(fMovementIncrement, 0, 0);
    216.                 transform.position += newpos;
    217.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    218.             }
    219.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    220.             bMoving = false;
    221.         }
    222.         if (currentCompass == Compass.E)
    223.         {
    224.             bMoving = true;
    225.             for (int g = 0; g < iMovementInterval; g++)
    226.             {
    227.                 newpos = new Vector3(0, 0, fMovementIncrement);
    228.                 transform.position += newpos;
    229.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    230.             }
    231.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    232.             bMoving = false;
    233.         }
    234.         if (currentCompass == Compass.W)
    235.         {
    236.             bMoving = true;
    237.             for (int g = 0; g < iMovementInterval; g++)
    238.             {
    239.                 newpos = new Vector3(0, 0, -fMovementIncrement);
    240.                 transform.position += newpos;
    241.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    242.             }
    243.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    244.             bMoving = false;
    245.         }
    246.  
    247.         var wait = new WaitForSeconds(0.1f);
    248.  
    249.  
    250.     }
    251.  
    252.     IEnumerator StepRight()
    253.     {
    254.         Vector3 newpos;
    255.         if (currentCompass == Compass.N)
    256.         {
    257.             bMoving = true;
    258.             for (int g = 0; g < iMovementInterval; g++)
    259.             {
    260.                 newpos = new Vector3(fMovementIncrement, 0, 0);
    261.                 transform.position += newpos;
    262.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    263.             }
    264.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    265.             bMoving = false;
    266.         }
    267.         if (currentCompass == Compass.S)
    268.         {
    269.             bMoving = true;
    270.             for (int g = 0; g < iMovementInterval; g++)
    271.             {
    272.                 newpos = new Vector3(-fMovementIncrement, 0, 0);
    273.                 transform.position += newpos;
    274.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    275.             }
    276.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    277.             bMoving = false;
    278.         }
    279.         if (currentCompass == Compass.E)
    280.         {
    281.             bMoving = true;
    282.             for (int g = 0; g < iMovementInterval; g++)
    283.             {
    284.                 newpos = new Vector3(0, 0, -fMovementIncrement);
    285.                 transform.position += newpos;
    286.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    287.             }
    288.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    289.             bMoving = false;
    290.         }
    291.         if (currentCompass == Compass.W)
    292.         {
    293.             bMoving = true;
    294.             for (int g = 0; g < iMovementInterval; g++)
    295.             {
    296.                 newpos = new Vector3(0, 0, fMovementIncrement);
    297.                 transform.position += newpos;
    298.                 yield return new WaitForSeconds(fWaitForSecondsInterval);
    299.             }
    300.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    301.             bMoving = false;
    302.         }
    303.  
    304.         var wait = new WaitForSeconds(0.1f);
    305.  
    306.     }
    307.  
    308.     IEnumerator RotateRight()
    309.     {
    310.         bRotating = true;
    311.  
    312.         for (int g = 0; g < iRotateInterval; g++)
    313.         {
    314.             transform.position = new Vector3(Mathf.Round(transform.position.x), fYLockPosition, Mathf.Round(transform.position.z));
    315.             transform.eulerAngles += new Vector3(0, fRotateIncrement, 0);
    316.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    317.         }
    318.  
    319.         switch (currentCompass)
    320.         {
    321.             case (Compass.W):
    322.                 currentCompass = Compass.N;
    323.                 Debug.Log("Compass is now N");
    324.                 //text.text ="N";
    325.                 break;
    326.             case (Compass.E):
    327.                 currentCompass = Compass.S;
    328.                 Debug.Log("Compass is now S");
    329.                 //text.text ="S";
    330.                 break;
    331.             case (Compass.S):
    332.                 currentCompass = Compass.W;
    333.                 Debug.Log("Compass is now W");
    334.                 //text.text ="W";
    335.                 break;
    336.             case (Compass.N):
    337.                 currentCompass = Compass.E;
    338.                 Debug.Log("Compass is now E");
    339.                 //text.text ="E";
    340.                 break;
    341.         }
    342.         yield return new WaitForSeconds(fWaitForSecondsInterval);
    343.         bRotating = false;
    344.  
    345.         var wait = new WaitForSeconds(fWaitForSecondsInterval);
    346.  
    347.  
    348.     }
    349.  
    350.     IEnumerator RotateLeft()
    351.     {
    352.         bRotating = true;
    353.         for (int g = 0; g < iRotateInterval; g++)
    354.         {
    355.             transform.position = new Vector3(Mathf.Round(transform.position.x), fYLockPosition, Mathf.Round(transform.position.z));
    356.             transform.eulerAngles += new Vector3(0, -fRotateIncrement, 0);
    357.             yield return new WaitForSeconds(fWaitForSecondsInterval);
    358.         }
    359.  
    360.         switch (currentCompass)
    361.         {
    362.             case (Compass.W):
    363.                 currentCompass = Compass.S;
    364.                 break;
    365.             case (Compass.E):
    366.                 currentCompass = Compass.N;
    367.                 break;
    368.             case (Compass.S):
    369.                 currentCompass = Compass.E;
    370.                 break;
    371.             case (Compass.N):
    372.                 currentCompass = Compass.W;
    373.                 break;
    374.         }
    375.         yield return new WaitForSeconds(fWaitForSecondsInterval);
    376.         bRotating = false;
    377.  
    378.         var wait = new WaitForSeconds(fWaitForSecondsInterval);
    379.  
    380.     }
    381. }
    382.  
     
    themoorkh, J5Dev and Tset_Tsyung like this.
  2. jasperh_unity

    jasperh_unity

    Joined:
    Jan 29, 2018
    Posts:
    1
    Thank you so much for this! How would you go about creating the tile map/level?
     
  3. DrakkathSenpai

    DrakkathSenpai

    Joined:
    Jun 13, 2017
    Posts:
    3
    Here's how I did it. It's sloppy, old, uncommented and poorly formatted, and probably not very efficient. I think the concept itself is sound, however.

    Basically, you first create your models (walls, floors, misc) that you want in the level in your 3D modeling package. I use Blender. Make sure that the ORIGIN of your object is where you want the position to be when it's instantiated in Unity. Basically, you want the center of your object to be at the coordinates to be "drawn" when the map is loaded. For whatever reason, that was the center of the object in my project:
    Create a folder named Resources in your project. This is where you will place all of the "tiles". First Import your 3D model, then place into scene to make sure everything is textured and oriented correctly. Once that's done, drag your GameObject into the Resources folder.

    You can repeat this for whatever object you want to place in your map.

    I used XML for the actual map, so that I could easily make changes directly within the editor. I created a Script with a public string to hold the XML so I could modify it in the inspector.

    Here's an example map XML for the code:
    Code (CSharp):
    1.  
    2. <data>
    3.    <map id="1" atlassize="8" posscale="2" rows="10" columns="20" layers="3" playerstartx="10" playerstarty="10" playerstartrot="180">
    4.       <atlas aid="1" src="grassfloor1" yoffset="0" />
    5.       <atlas aid="2" src="hedgecolumn1" yoffset="0" />
    6.       <atlas aid="3" src="treeanimated1" yoffset="0" />
    7.       <atlas aid="4" src="grassbillboard1" yoffset="-1" />
    8.       <atlas aid="5" src="grassbillboard2" yoffset="-1" />
    9.       <atlas aid="6" src="lamppost1" yoffset="0" />
    10.       <atlas aid="7" src="rock1" yoffset="0" />
    11.       <atlas aid="8" src="torchlamp1" yoffset="-1" />
    12.       <layer posy="0" posscaley="1">
    13. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    14. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    15. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    16. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    17. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    18. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    19. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    20. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    21. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    22. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    23.       </layer>
    24.       <layer posy="1" posscaley="1">
    25. 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    26. 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    27. 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    28. 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    29. 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    30. 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    31. 2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    32. 2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    33. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
    34. 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,</layer>
    35.       <layer posy="1" posscaley="1">
    36. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    37. 0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,
    38. 0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,
    39. 0,0,0,0,3,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,
    40. 0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,
    41. 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,
    42. 0,0,0,0,0,8,4,0,0,6,0,0,0,0,0,0,0,0,0,0,
    43. 0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,
    44. 0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,
    45. 0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    46. </layer>
    47.    </map>
    48. </data>
    49.      
    And here's the C# script for parsing it, instantiating the objects:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic; //Needed for Lists
    4. using System.Xml;
    5. using System.IO;
    6. using System.Text;
    7.  
    8. public class MapLoader : MonoBehaviour {
    9.     [SerializeField]
    10.     public string mapString;
    11.     [SerializeField]
    12.     public Transform levelObject;
    13.  
    14.  
    15.     void Start () {
    16.         StartCoroutine(LoadMap());
    17.     }
    18.  
    19.     void Update () {
    20.    
    21.     }
    22.  
    23.     IEnumerator CreatePrefab(string name, Vector3 position)
    24.     {
    25.             GameObject goSearch = GameObject.Find(name);
    26.             if (goSearch == null)
    27.             {
    28.                 goSearch = new GameObject(name);
    29.                 goSearch.transform.parent = levelObject;
    30.             }
    31.             GameObject go = (GameObject)Instantiate(Resources.Load(name));
    32.             go.transform.SetParent(goSearch.transform);
    33.             go.transform.position = new Vector3(position.x, position.z, position.y);
    34.             yield return new WaitForSeconds(0f);
    35.     }
    36.  
    37.     IEnumerator LoadMap() //XML reader for loading map objects
    38.     {
    39.         int ID = 0;
    40.         int Rows = 0;
    41.         int Columns = 0;
    42.         int Layers = 0;
    43.         int posScale = 0;
    44.         int posScaleY = 0;
    45.         int atlasSize = 0;
    46.         Dictionary<int, string> tileAtlas = new Dictionary<int, string>();
    47.         Dictionary<int, int> tileAtlasYOffset = new Dictionary<int, int>();
    48.         using (XmlReader reader = XmlReader.Create(new StringReader(mapString)))
    49.         {
    50.             reader.ReadToFollowing("map");
    51.             ID = System.Int32.Parse(reader.GetAttribute("id"));
    52.             atlasSize = System.Int32.Parse(reader.GetAttribute("atlassize"));
    53.             posScale = System.Int32.Parse(reader.GetAttribute("posscale"));
    54.             Rows = System.Int32.Parse(reader.GetAttribute("rows"));
    55.             Columns = System.Int32.Parse(reader.GetAttribute("columns"));
    56.             Layers = System.Int32.Parse(reader.GetAttribute("layers"));
    57.             for (int atlasentry = 1; atlasentry <= atlasSize; atlasentry++)
    58.             {
    59.                 try
    60.                 {
    61.                     reader.ReadToFollowing("atlas");
    62.                     tileAtlas.Add(atlasentry, reader.GetAttribute("src"));
    63.                     tileAtlasYOffset.Add(atlasentry, System.Int32.Parse(reader.GetAttribute("yoffset")));
    64.                 }
    65.                 catch { }
    66.             }
    67.             for (int layer = 0; layer <= Layers; layer++)
    68.             {
    69.                 reader.ReadToFollowing("layer");
    70.                 posScaleY = System.Int32.Parse(reader.GetAttribute("posscaley"));
    71.                 int posy = System.Int32.Parse(reader.GetAttribute("posy"));
    72.                 Debug.Log(posScaleY.ToString() + '-' + posy.ToString());
    73.                 int row = 0;
    74.                     int column = 0;
    75.                     foreach (string x in reader.ReadInnerXml().ToString().Replace("\t", "").Replace(" ", "").Split(','))
    76.                     {
    77.                     if (column == Columns)
    78.                     { column = 0; row += 1; }
    79.                     try
    80.                     {
    81.                         if (x != "0" && x != null)
    82.                         {
    83.                             string src = "No Prefab Found";
    84.                             int yoffset = 0;
    85.                             tileAtlas.TryGetValue(System.Int32.Parse(x), out src);
    86.                             tileAtlasYOffset.TryGetValue(System.Int32.Parse(x), out yoffset);
    87.                             StartCoroutine(CreatePrefab(src, new Vector3(row * posScale, column * posScale, (posy * posScaleY) + yoffset)));
    88.                         }
    89.                     }
    90.                     catch { }
    91.                         column++;
    92.                     }
    93.                     yield return new WaitForSeconds(0f);
    94.             }
    95.            
    96.             }
    97.     }
    98. }
    99.  
     
  4. themoorkh

    themoorkh

    Joined:
    Aug 4, 2018
    Posts:
    2
    I used this script to do a very simple 3D maze. It worked great, thanks!
     
  5. themoorkh

    themoorkh

    Joined:
    Aug 4, 2018
    Posts:
    2
    Now, being really new to this (doing this 3D maze was my personal challenge right after the basic tutorials), I can't say I can follow your script in every detail.
    That said, I wondered if I could make the player stop in my grid-based world when hitting a solid block or a wall. Further down the line, I'd even like the player to fall down to the floor below when moving beyond the edge of the floor.
    To do this, I first tried to simply add a rigidbody with gravity on to my playercamera object (my level objects having physics, too). This led to some glitches and did not work at all.
    Then I tried to attach the camera as a child really close to an invisible cube, instead (small enough to be able to turn without scraping the walls). This worked to stop the player from moving through objects, and your script nicely re-centered the player after the collision. Moving over an edge, though, proved ...interesting, tumbling my camera along with the player cube in completely absurd ways.
    I'm aware that I'm in over my head here, but I also think this is an excellent learning opportunity. Still, I seem a bit stuck: aside from my approach certainly being horribly messy and inefficient, why is my cube not dropping properly? Any help would be appreciated greatly.
     
  6. YangtheX-Y-H

    YangtheX-Y-H

    Joined:
    Oct 29, 2018
    Posts:
    1
    Thank you, you’re amazing! I use it to my Turn-based game like shin megami tensei, it helps a lot.
     
  7. Hemomancer

    Hemomancer

    Joined:
    Mar 13, 2019
    Posts:
    1
    You're doing work of Gods Senpai!