Search Unity

Improve script efficiency

Discussion in 'Scripting' started by Burton-kun, Oct 5, 2015.

  1. Burton-kun

    Burton-kun

    Joined:
    Aug 6, 2015
    Posts:
    50
    Hi guys!
    I need some help to fix this script as better I can.
    Here's my situation:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Collisions : MonoBehaviour {
    6.     public static int i = 1;
    7.     public static int j = 1;
    8.     public static bool canMove;
    9.     public static int[,] TerrainTable = new int[40,40];
    10.  
    11.     public void Update () {
    12.         if (!NextTilePassable()){
    13.             canMove = false;
    14.         } else {
    15.             canMove = true;
    16.         }
    17.     }
    18.  
    19.     public bool NextTilePassable() {
    20.         if (TerrainTable [i - 1, j] == 00) {
    21.             return false;
    22.         }
    23.  
    24.         if (TerrainTable [i + 1, j] == 00) {
    25.             return false;
    26.         }
    27.  
    28.         if (TerrainTable [i, j - 1] == 00) {
    29.             return false;
    30.         }
    31.  
    32.         if (TerrainTable [i, j + 1] == 00) {
    33.             return false;
    34.         }
    35.         return true;
    36.     }
    37.  
    Code (CSharp):
    1.  
    2. sing UnityEngine;
    3. using System;
    4.  
    5. class PlayerMovements : MonoBehaviour {
    6.     private Vector2 input;
    7.     private bool isMoving = false;
    8.     private Vector3 startPosition;
    9.     private Vector3 endPosition;
    10.     private float t;
    11.     private float factor;
    12.  
    13.  
    14. public void Update() {
    15.         Collisions.i = (int)ConvertPosToTileCoords().z;
    16.         Collisions.j = (int)ConvertPosToTileCoords().x;
    17.         if (!isMoving) {
    18.             input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    19.  
    20.             if (input != Vector2.zero && Collisions.canMove) {
    21.                 StartCoroutine(move(transform));
    22.             }
    23.         }
    24.     }
    25.  
    26.     private Vector3 ConvertPosToTileCoords(){
    27.         var GlobalplayerPos = transform.position;
    28.         var CurrentMapID = Data.PlayerGame.CurrentMapID;
    29.         var RegionX = Data.Outdoors[CurrentMapID].RegionPosition.x;
    30.         var RegionY = Data.Outdoors[CurrentMapID].RegionPosition.z;
    31.         var gridsize = Data.Map.gridSize;
    32.         var mapSize = 40;
    33.         var Localposition = new Vector3 ((GlobalplayerPos.x - ((gridsize*mapSize) * ( RegionX - 1))), 0, (Math.Abs(GlobalplayerPos.z) - ((gridsize*mapSize) * ( RegionY - 1))));
    34.         var position = new Vector3 ((Localposition.x/gridsize), GlobalplayerPos.y, (Localposition.z/gridsize));
    35.         position = new Vector3((int)Math.Round(position.x, 5, MidpointRounding.ToEven), 0, (int)Math.Round(position.z, 5, MidpointRounding.ToEven));
    36.         var col = (int)position.x;
    37.         var row = (int)position.z;
    38.         if (row < 0) {
    39.             row = 0;
    40.         }
    41.         if (row > 39) {
    42.             row = 39;
    43.         }
    44.         if (col < 0) {
    45.             col = 0;
    46.         }
    47.         if (col > 39) {
    48.             col = 39;
    49.         }
    50.         Collisions.TerrainTable = Data.Outdoors[CurrentMapID].terrainTable;
    51.         return new Vector3(col, 0, row);
    52.     }
    53.  
    54.  
    55.     public IEnumerator move(Transform transform) {
    56.         isMoving = true;
    57.         var gridsize = Data.Map.gridSize;
    58.         var moveSpeed = Data.Player.moveSpeed;
    59.         startPosition = transform.position;
    60.         t = 0;
    61.  
    62.         endPosition = new Vector3(startPosition.x + System.Math.Sign(input.x) * Data.Map.gridSize,
    63.                                  startPosition.y, startPosition.z + System.Math.Sign(input.y) * Data.Map.gridSize);
    64.      
    65.         if(input.x != 0 && input.y != 0) {
    66.             factor = 0.7071f;
    67.         } else {
    68.             factor = 1f;
    69.         }
    70.  
    71.         if (Input.GetButton("DeleteButton")) {
    72.             moveSpeed = 180;
    73.         } else {
    74.             moveSpeed = 90;
    75.         }
    76.      
    77.         while (t < 1f) {
    78.             t += Time.deltaTime * (moveSpeed/gridsize) * factor;
    79.             transform.position = Vector3.Lerp(startPosition, endPosition, t);
    80.             yield return null;
    81.         }
    82.      
    83.         isMoving = false;
    84.         yield return 0;
    85.     }
    86. }
    87.  
    By using these two scripts, I can avoid the player, that moves using a Vector3.lerp, to cross walls or trees.
    The main problem is that the calculation isn't speed enough. Cause if i keep walking or moving, sooner or later it will cross a wallk and be stuck in it.
    As you can see from the examples, I use a boolean variable to access a IEnumeration function, where the movement is calculated. Apparently is not enough. There is a better way to do what I'm trying to do? Thank you.
     
    Last edited: Oct 5, 2015
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I'm having a hard time understanding exactly what you're asking for, but I have two things that may help you (or, help others help you):

    1) Please post the actual code giving you trouble. Are you worried that we're going to steal it? If it's really long, post it on a pastebin and link to it. We can't help you with the code you've posted there.

    2) Whatever your problem is, it doesn't sound like an efficiency problem. An inefficient script would cause low framerates or lag. This seems more like a problem of faulty logic.
     
  3. Burton-kun

    Burton-kun

    Joined:
    Aug 6, 2015
    Posts:
    50
    I wasn't afraid of thievery. I just wanted to be synthetic.
    I edited the first post with the actual scripts.

    Yes I was wrong. I'm asking for a better logic, to prevent my player to walk on tile where the correspondent array value is 00. It works but I think there is a better way, 'cause If I force the player to move in a certain direction, or start to press random keyes, sooner or later it will cross a collision tile. I know that no one would play with the input.keys as I did (even if I'm not so sure), but I want it to work anyway.
     
  4. Burton-kun

    Burton-kun

    Joined:
    Aug 6, 2015
    Posts:
    50
    I'm still stuck with the script!
     
  5. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    It looks like you're applying the "movement" code before you actually check the tile? What you should do is, get a "projected" position, i.e., what position will you be in if you move, check if that tile is passable, then continue the movement.
     
  6. Burton-kun

    Burton-kun

    Joined:
    Aug 6, 2015
    Posts:
    50
    You're right! I fixed the script and it works perfectly. Thank you so much.