Hello,
I am working on a game where the player has the ability to swipe and the in game vehicle will follow their movement. As long as the player swipes and removes their finger, the game will perform fine. However, if the player decides to keep their finger just ahead of the vehicle for the vehicle to follow throughout the level, the game will experience extreme lag. I thought I had isolated the problem to coincide with the error message “ArgumentOutOfRangeException: Argument is out of range. Parameter name: index”, but I’m still missing something.
The error message directs me to the script below, but I think it has more to do with an array that is being called but is not yet created?
private void MoveToNodes()
{
//first makes sure the array is not 0 in length and that the last item in the array actually has a pathnode
if (pathNodes.Count >= 1 pathNodes[pathNodes.Count - 1] != null)
{
//audio.PlayOneShot(Engine);
//moves this object forward (towards current pathnode)
this.transform.position += this.transform.forward * moveSpeed * Time.deltaTime;
//Gradually turns the Enemy to face current pathnode
this.transform.rotation = Quaternion.Slerp
(this.transform.rotation,Quaternion.LookRotation(pathNodes[currNode].position - this.transform.position),rotationSpeed * Time.deltaTime);
}
}
I just can’t seem to figure out what I am missing. Any help would be appreciated and all relevant code that pertains to the swipe movement is below. Essentially when the player swipes, path nodes are created that the vehicle follows and then they are destroyed.
AIPathnodeTracker.cs
//Script by Devin Curry
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//put this script on the Enemy
public class AIPathnodeTracker : MonoBehaviour
{
public float moveSpeed = 1.0f;
public float rotationSpeed = 20.0f;
public List<Transform> pathNodes;
//public AudioClip Engine;
[HideInInspector]
public int currNode = 0;
//used to keep track of a previous player position to bounce back to when he collides
private GameObject storedPos = null;
private void Start ()
{
if(this.tag == "Player")
{
//starts keeping track of last positions
storedPos = GameObject.Find("StoredPos");
StartCoroutine(LastPositionTracker());
}
//makes sure enemy faces first pathnode
this.transform.LookAt(pathNodes[0]);
//audio.PlayOneShot(Engine);
}
private void Update ()
{
if(this.tag == "Player" ControlScheme.currentControlMode == ControlScheme.ControlMode.SwipeMode)
{
//audio.PlayOneShot(Engine);
MoveToNodes();
}
else if (this.tag == "Enemy")
{
//audio.PlayOneShot(Engine);
MoveToNodes();
}
}
private void OnCollisionEnter(Collision col)
{
//if the player collides with something oher than the ground it will bounce back away from the wall a bit and clear all nodes
if(this.tag == "Player" col.gameObject.name != "Collision-Ground" ControlScheme.currentControlMode == ControlScheme.ControlMode.SwipeMode)
{
//Vector3 colVector = (storedPos.transform.position - this.transform.position).normalized;
Vector3 colVector = (col.transform.position - this.transform.position).normalized;
this.transform.position = storedPos.transform.position;
pathNodes.Clear();
currNode = 0; //0
}
}
IEnumerator LastPositionTracker ()
{
//endless loop
while(true)
{
// Debug.Log(this.transform.position);
//stores player transform
storedPos.transform.position = this.transform.position;
//waits a bit before caching new location
yield return new WaitForSeconds(0.05f); //0.5
}
}
private void MoveToNodes()
{
//first makes sure the array is not 0 in length and that the last item in the array actually has a pathnode
if (pathNodes.Count >= 1 pathNodes[pathNodes.Count - 1] != null)
{
//audio.PlayOneShot(Engine);
//moves this object forward (towards current pathnode)
this.transform.position += this.transform.forward * moveSpeed * Time.deltaTime;
//Gradually turns the Enemy to face current pathnode
this.transform.rotation = Quaternion.Slerp
(this.transform.rotation,Quaternion.LookRotation(pathNodes[currNode].position - this.transform.position),rotationSpeed * Time.deltaTime);
}
}
}
SwipeMovement.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SwipeMovement : MonoBehaviour
{
private GameObject player = null;
//changes constantly, TouchPositionGrabber will grab it ever "touchPositionGrabberFrequency" seconds
private Vector3 worldSpaceHitPoint;
//Used for placing nodes
private bool startPlacingNodes = false;
public float touchPositionGrabberFrequency = 0.5f;//time inbetween grabbing the touch position
public GameObject playerPathnodes = null;
[HideInInspector]
public AIPathnodeTracker trkr;
void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
trkr = player.GetComponent(typeof(AIPathnodeTracker)) as AIPathnodeTracker;
}
void Update()
{
if(ControlScheme.currentControlMode == ControlScheme.ControlMode.SwipeMode)
{
#if UNITY_ANDROID || UNITY_IPHONE
//first checks to see if there is a touch, then checks to see if the touch began
if(startPlacingNodes Input.touches.Length <= 0)
{
startPlacingNodes = false;
}
else if (Input.touches.Length > 0 Input.GetTouch(0).phase==TouchPhase.Began)
{
//PlaceOneNode();
}
else if (Input.touches.Length > 0 Input.GetTouch(0).phase==TouchPhase.Moved)
{
//converts touch position to ray
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
//converts ray to worldSpace and appends player's y position
worldSpaceHitPoint = new Vector3(hitInfo.point.x, player.transform.position.y, hitInfo.point.z);
}
if(!startPlacingNodes)
{
//Commence grabbing
startPlacingNodes = true;
GrabStarter();
}
//Debug.Log("Touch Move Position " + Input.GetTouch(0).position);//finds finger position each movement (Vector2)
//Debug.Log("Player position: " + player.transform.position);//finds player position (Vector 3)
}
#endif
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR || UNITY_STANDALONE_LINUX || UNITY_WEBPLAYER || UNITY_FLASH
if(startPlacingNodes Input.GetMouseButtonUp(0))
{
startPlacingNodes = false;
}
else if (Input.GetMouseButtonDown(0))
{
PlaceOneNode();
}
else if (Input.GetMouseButton(0))//mouse draging
{
//converts touch position to ray
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
//converts ray to worldSpace and appends player's y position
worldSpaceHitPoint = new Vector3(hitInfo.point.x, player.transform.position.y, hitInfo.point.z);
}
if(!startPlacingNodes)
{
//Commence grabbing
startPlacingNodes = true;
GrabStarter();
}
}
#endif
}
}
void GrabStarter()
{
//resets list and counter and destroys old nodes
/* foreach(Transform currNode in trkr.pathNodes)
{
Destroy (currNode.gameObject);
}
*/
trkr.pathNodes.Clear();
trkr.currNode = 0;
StartCoroutine(TouchPositionGrabber()); //grabs the current position and waits
}
//not in use now places node at 0,0,0 for some reason
void PlaceOneNode()
{
//places nodes
GameObject tempNode = (GameObject)GameObject.Instantiate(playerPathnodes);
tempNode.transform.position = worldSpaceHitPoint;
//adds newly created node to the List
trkr.pathNodes.Add(tempNode.transform);
//trkr.currNode++;
}
//grabs positions and places pathnodes nodes like a boss
IEnumerator TouchPositionGrabber ()
{
if(ControlScheme.currentControlMode == ControlScheme.ControlMode.SwipeMode)
{
GameObject tempNode = null;
while (startPlacingNodes)
{
//places nodes
tempNode = (GameObject)GameObject.Instantiate(playerPathnodes);
tempNode.transform.position = worldSpaceHitPoint;
//Debug.Log("placing node");
//adds newly created node to the List
trkr.pathNodes.Add(tempNode.transform);
yield return new WaitForSeconds(touchPositionGrabberFrequency);
}
}
}
}