I'm developing a game where the character moves along a predefined path and I want to use the A* algorithm to look for this path. The script I have to do this movement is this one, to look for the path:
public class PathManager : MonoBehaviour {
public float walkSpeed = 5.0f;
public LayerMask mask;
public List<Waypoint> allWayPoints = new List<Waypoint>();
private Stack<Vector3> currentPath;
private Vector3 currentWaypointPosition;
private float moveTimeTotal;
private float moveTimeCurrent;
private Transform cam;
private void Start() {
cam = Camera.main.transform;
}
void Update() {
if (currentPath != null && currentPath.Count > 0) {
if (moveTimeCurrent < moveTimeTotal) {
moveTimeCurrent += Time.deltaTime;
if (moveTimeCurrent > moveTimeTotal)
moveTimeCurrent = moveTimeTotal;
Vector3 temp = currentPath.Peek();
temp.y = 1;
currentWaypointPosition.y = 1;
transform.position = Vector3.Lerp(currentWaypointPosition, temp, moveTimeCurrent / moveTimeTotal);
} else {
currentWaypointPosition = currentPath.Pop();
if (currentPath.Count == 0)
Stop();
else {
moveTimeCurrent = 0;
moveTimeTotal = (currentWaypointPosition - currentPath.Peek()).sqrMagnitude / walkSpeed;
}
}
}
if (Input.GetButtonDown("Fire1")) {
Stop();
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(cam.transform.position, ray.direction, out hit)) {
Debug.Log(hit.collider);
Waypoint temp = hit.collider.GetComponent<Waypoint>();
Vector3 location = temp.GetCurrentPosition();
Debug.Log(location);
NavigateTo(location);
}
}
}
public void NavigateTo(Vector3 destination)
{
currentPath = new Stack<Vector3> ();
var currentNode = FindClosestWaypoint (transform.position);
var endNode = FindClosestWaypoint (destination);
if (currentNode == null || endNode == null || currentNode == endNode)
return;
var openList = new SortedList<float, Waypoint> ();
var closedList = new List<Waypoint> ();
openList.Add (0, currentNode);
currentNode.previous = null;
currentNode.distance = 0f;
while (openList.Count > 0)
{
currentNode = openList.Values[0];
openList.RemoveAt (0);
var dist = currentNode.distance;
closedList.Add (currentNode);
if (currentNode == endNode){
break;
}
foreach (var neighbor in currentNode.neighbors)
{
if (closedList.Contains (neighbor) || openList.ContainsValue (neighbor))
continue;
neighbor.previous = currentNode;
neighbor.distance = dist + (neighbor.transform.position - currentNode.transform.position).sqrMagnitude;
var distanceToTarget = (neighbor.transform.position - endNode.transform.position).sqrMagnitude;
openList.Add (neighbor.distance + distanceToTarget, neighbor);
}
}
if (currentNode == endNode) {
while (currentNode.previous != null){
currentPath.Push (currentNode.transform.position);
currentNode = currentNode.previous;
}
currentPath.Push (transform.position);
}
}
public void Stop() {
currentPath = null;
moveTimeTotal = 0;
moveTimeCurrent = 0;
currentWaypointPosition = Vector3.zero;
}
private Waypoint FindClosestWaypoint(Vector3 target){
GameObject closest = null;
float closestDist = Mathf.Infinity;
foreach (var waypoint in allWayPoints) {
var dist = (waypoint.transform.position - target).sqrMagnitude;
if (dist < closestDist) {
closest = waypoint.gameObject;
closestDist = dist;
}
}
if (closest != null){
return closest.GetComponent<Waypoint> ();
}
return null;
}
}
And this other script on the "walkable" elements:
public class Waypoint : MonoBehaviour {
public List<Waypoint> neighbors;
[Range(0.1f, .5f)]
public float range = 0.1f;
public Waypoint previous;
public float distance;
public bool active = true;
public Vector3 GetCurrentPosition() {
return (transform.position + transform.up - transform.up * 0.5f);
}
void OnDrawGizmos() {
if (neighbors == null)
return;
Gizmos.color = Color.red;
Gizmos.DrawSphere(GetCurrentPosition(), range);
Gizmos.color = Color.blue;
foreach (var neighbor in neighbors) {
if (neighbor != null)
Gizmos.DrawLine (GetCurrentPosition(), neighbor.GetCurrentPosition());
}
}
}
However, I have two problems using this code, the first problem is, I can only put two directions to move, and the second problem is that I can't add obstacles on the way.
Related
So I am trying to create a game where a player can swing with a rope/grappling hook, similar to a game like Teeworlds. The grappling hook feels great when I am hooked onto things and I am using my movement keys, the problem comes when I let go of my left or right movement keys the character slowly floats down. Feels like the gravity gets put to like 0.00001 on the character until i let go of the grappling hook button.
Will post a gif of how it looks and the code I am using for the grappling hook.
Thanks,
The Pepsidi.
Game Play of Issue
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class GrappleSystem : MonoBehaviour
{
public GameObject grappleAnchor;
public DistanceJoint2D grappleJoint;
public Transform crosshair;
public PlayerMovement playerMovement;
private bool grappleAttached;
private Vector2 playerPosition;
private Rigidbody2D grappleAnchorRb;
private SpriteRenderer grappleAnchorSprite;
public LineRenderer grappleRenderer;
public LayerMask grappleLayerMask;
private float grappleMaxCastDistance = 20f;
private List<Vector2> grapplePositions = new List<Vector2>();
private bool distanceSet;
void Awake()
{
grappleJoint.enabled = false;
playerPosition = transform.position;
grappleAnchorRb = grappleAnchor.GetComponent<Rigidbody2D>();
grappleAnchorSprite = grappleAnchor.GetComponent<SpriteRenderer>();
}
void Update()
{
var worldMousePosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f));
var facingDirection = worldMousePosition - transform.position;
var aimAngle = Mathf.Atan2(facingDirection.y, facingDirection.x);
if (aimAngle < 0f)
{
aimAngle = Mathf.PI * 2 + aimAngle;
}
var aimDirection = Quaternion.Euler(0, 0, aimAngle * Mathf.Rad2Deg) * Vector2.right;
playerPosition = transform.position;
if (!grappleAttached)
{
SetCrosshairPosition(aimAngle);
}
HandleInput(aimDirection);
UpdateGrapplePositions();
}
private void SetCrosshairPosition(float aimAngle)
{
var x = transform.position.x + 5f * Mathf.Cos(aimAngle);
var y = transform.position.y + 5f * Mathf.Sin(aimAngle);
var crossHairPosition = new Vector3(x, y, 0);
crosshair.transform.position = crossHairPosition;
}
private void HandleInput(Vector2 aimDirection)
{
if (Input.GetMouseButtonDown(1))
{
if (grappleAttached) return;
grappleRenderer.enabled = true;
var hit = Physics2D.Raycast(playerPosition, aimDirection, grappleMaxCastDistance, grappleLayerMask);
if (hit.collider != null)
{
grappleAttached = true;
if (!grapplePositions.Contains(hit.point))
{
transform.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, 5f), ForceMode2D.Force);
grapplePositions.Add(hit.point);
grappleJoint.distance = Vector2.Distance(playerPosition, hit.point);
grappleJoint.enabled = true;
grappleAnchorSprite.enabled = true;
}
}
else
{
grappleRenderer.enabled = false;
grappleAttached = false;
grappleJoint.enabled = false;
}
}
if (Input.GetMouseButtonUp(1))
{
ResetGrapple();
}
}
private void ResetGrapple()
{
grappleJoint.enabled = false;
grappleAttached = false;
//playerMovement.isSwinging = false;
grappleRenderer.positionCount = 2;
grappleRenderer.SetPosition(0, transform.position);
grappleRenderer.SetPosition(1, transform.position);
grapplePositions.Clear();
grappleAnchorSprite.enabled = false;
}
private void UpdateGrapplePositions()
{
if (!grappleAttached)
{
return;
}
grappleRenderer.positionCount = grapplePositions.Count + 1;
for (var i = grappleRenderer.positionCount - 1; i >= 0; i--)
{
if (i != grappleRenderer.positionCount - 1)
{
grappleRenderer.SetPosition(i, grapplePositions[i]);
if (i == grapplePositions.Count - 1 || grapplePositions.Count == 1)
{
var grapplePosition = grapplePositions[grapplePositions.Count - 1];
if (grapplePositions.Count == 1)
{
grappleAnchorRb.transform.position = grapplePosition;
if (!distanceSet)
{
grappleJoint.distance = Vector2.Distance(transform.position, grapplePosition);
distanceSet = true;
}
}
else
{
grappleAnchorRb.transform.position = grapplePosition;
if (!distanceSet)
{
grappleJoint.distance = Vector2.Distance(transform.position, grapplePosition);
distanceSet = true;
}
}
}
else if (i - 1 == grapplePositions.IndexOf(grapplePositions.Last()))
{
var grapplePosition = grapplePositions.Last();
grappleAnchorRb.transform.position = grapplePosition;
if (!distanceSet)
{
grappleJoint.distance = Vector2.Distance(transform.position, grapplePosition);
distanceSet = true;
}
}
}
else
{
grappleRenderer.SetPosition(i, transform.position);
}
}
}
}
First I find the objects that interest me using GameObject.FindGameObjectsWithTag. And I bring them into one array All[ ] . I create NavMeshAgent>. I drive the agent to selected points on the map. Until he meets someone from the All[ ] array. And it would seem that everything works, but BUT. The agent only triggers on the last object in the array. I sat for 2 days, tried many ways, the result is the same, it can run the array not through ( foreach or for ) . Maybe there is a complex solution to the problem. Or even another way, I'm in the programming of bread, but I try my best. Any idea is accepted and tested. Thanks!!!
public void getTarget(GameObject[] targets) runs through array objects - this is where the problem lies
public GameObject[] Concat(GameObject[] first, GameObject[] second, GameObject[] third) concatenates arrays of objects
public void moveToTarget(Vector3 target) points to the target for the
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MinionMoveByLine : MonoBehaviour
{
public enum MovementType
{
Moveing,
Learp
}
//Переменные для перемещения по карте
public MovementType type = MovementType.Moveing;
public NavMeshLineToMove MyLine;
public float speed = 1;
public float maxDistance = .3f;
private NavMeshAgent enemy;
//Переменные для растояний и приоритета крипов
private GameObject[] minions;
private GameObject[] towers;
private GameObject[] players;
private GameObject[] All;
public GameObject minion;
private Vector3[] position;
private Vector3 targetPosition;
private float distanceVisionForAttack = 6f;
private float radiusOfAttack = 2f;
private IEnumerator<Transform> pointInPath;
// Start is called before the first frame update
void Start()
{
minions = GameObject.FindGameObjectsWithTag("minion");
towers = GameObject.FindGameObjectsWithTag("tower");
players = GameObject.FindGameObjectsWithTag("player");
All = Concat(players, towers, minions);
Debug.Log("minions "+ minions.Length);
Debug.Log("towers " + towers.Length);
Debug.Log("players " + players.Length);
minion = (GameObject)this.gameObject;
enemy = GetComponent<NavMeshAgent>();
if (MyLine == null)
{
Debug.Log("Line Not Set");
return;
}
pointInPath = MyLine.GetNextPathPoint();
pointInPath.MoveNext();
if (pointInPath.Current == null)
{
Debug.Log("Need point to move");
return;
}
transform.position = pointInPath.Current.position;
}
void LateUpdate()
{
Vector3 position = minion.transform.position;
if (pointInPath == null || pointInPath.Current == null)
{
return;
}
foreach(var obj in All)
{
Debug.Log(All.Length);
Debug.Log(obj);
}
getTarget(All);
var distanceSqure = (transform.position - pointInPath.Current.position).sqrMagnitude;
if (distanceSqure < maxDistance * maxDistance)
{
pointInPath.MoveNext();
}
}
public GameObject[] Concat(GameObject[] first, GameObject[] second, GameObject[] third)
{
GameObject[] Concated = new GameObject[first.Length+second.Length+third.Length];
for (int i = 0; i < first.Length; i++)
{
Concated[i] = first[i];
}
for (int i = 0; i < second.Length; i++)
{
Concated[first.Length + i] = second[i];
}
for (int i = 0; i < third.Length; i++)
{
Concated[first.Length + second.Length + i] = third[i];
}
return Concated;
}
public void getTarget(GameObject[] targets)
{
Vector3 minionPosition = this.transform.position;
foreach (GameObject go in targets)
{
Transform transform = go.GetComponent<Transform>();
Vector3 transformPosition = transform.position;
float distanceToTarget = Vector3.Distance(transformPosition, minionPosition);
if (distanceToTarget <= distanceVisionForAttack && distanceToTarget > radiusOfAttack)
{
moveToTarget(transformPosition);
}else if(distanceToTarget <= radiusOfAttack)
{
moveToTarget(minion.transform.position);
}
else if(type == MovementType.Moveing && distanceToTarget > distanceVisionForAttack)
{
enemy.SetDestination(pointInPath.Current.position);
}
}
var distanceSqure = (transform.position - pointInPath.Current.position).sqrMagnitude;
if (distanceSqure < maxDistance * maxDistance)
{
pointInPath.MoveNext();
}
}
public void moveToTarget(Vector3 target)
{
enemy.SetDestination(target);
}
}
result of starting scene
What is happening in redactor - YouTube
I leave for those who in the future will face the same stupidity as me, change
getTarget ( );
new variables added
GameObject currentTarget;
float dist = Mathf.Infinity;
and cycle
foreach(GameObject go in targets)
{
Vector3 targetPosition = go.transform.position;
float distanceToTarget = Vector3.Distance(targetPosition,
minionPosition);
if (distanceToTarget < dist)
{
dist = distanceToTarget;
currentTarget = go;
}
}
Special thanks to BugFinder
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MinionMoveByLine : MonoBehaviour
{
public enum MovementType
{
Moveing,
Learp
}
//Переменные для перемещения по карте
public MovementType type = MovementType.Moveing;
public NavMeshLineToMove MyLine;
public float speed = 1;
public float maxDistance = .3f;
private NavMeshAgent enemy;
//Переменные для растояний и приоритета крипов
private GameObject[] minions;
private GameObject[] towers;
private GameObject[] players;
private GameObject[] All;
public GameObject minion;
private Vector3[] position;
private Vector3 targetPosition;
private float distanceVisionForAttack = 6f;
private float radiusOfAttack = 2f;
GameObject currentTarget;
float dist = Mathf.Infinity;
private IEnumerator<Transform> pointInPath;
// Start is called before the first frame update
void Start()
{
minions = GameObject.FindGameObjectsWithTag("minion");
towers = GameObject.FindGameObjectsWithTag("tower");
players = GameObject.FindGameObjectsWithTag("player");
All = Concat(players, towers, minions);
Debug.Log("minions "+ minions.Length);
Debug.Log("towers " + towers.Length);
Debug.Log("players " + players.Length);
//currentTarget = All[0];
minion = (GameObject)this.gameObject;
enemy = GetComponent<NavMeshAgent>();
if (MyLine == null)
{
Debug.Log("Line Not Set");
return;
}
pointInPath = MyLine.GetNextPathPoint();
pointInPath.MoveNext();
if (pointInPath.Current == null)
{
Debug.Log("Need point to move");
return;
}
transform.position = pointInPath.Current.position;
}
void LateUpdate()
{
Vector3 position = minion.transform.position;
if (pointInPath == null || pointInPath.Current == null)
{
return;
}
foreach(var obj in All)
{
Debug.Log(All.Length);
Debug.Log(obj);
}
getTarget(All);
var distanceSqure = (transform.position - pointInPath.Current.position).sqrMagnitude;
if (distanceSqure < maxDistance * maxDistance)
{
pointInPath.MoveNext();
}
}
public GameObject[] Concat(GameObject[] first, GameObject[] second, GameObject[] third)
{
GameObject[] Concated = new GameObject[first.Length+second.Length+third.Length];
for (int i = 0; i < first.Length; i++)
{
Concated[i] = first[i];
}
for (int i = 0; i < second.Length; i++)
{
Concated[first.Length + i] = second[i];
}
for (int i = 0; i < third.Length; i++)
{
Concated[first.Length + second.Length + i] = third[i];
}
return Concated;
}
public void getTarget(GameObject[] targets)
{
Vector3 minionPosition = this.transform.position;
foreach (GameObject go in targets)
{
Vector3 targetPosition = go.transform.position;
float distanceToTarget = Vector3.Distance(targetPosition, minionPosition);
if (distanceToTarget < dist)
{
dist = distanceToTarget;
currentTarget = go;
}
}
float distanceToCurrentTarget = Vector3.Distance(currentTarget.transform.position, minionPosition);
if (distanceToCurrentTarget <= distanceVisionForAttack && distanceToCurrentTarget > radiusOfAttack)
{
moveToTarget(currentTarget);
}
else if (distanceToCurrentTarget <= radiusOfAttack)
{
moveToTarget(minion);
}
else if (type == MovementType.Moveing && distanceToCurrentTarget > distanceVisionForAttack)
{
dist = Mathf.Infinity;
enemy.SetDestination(pointInPath.Current.position);
}
var distanceSqure = (transform.position - pointInPath.Current.position).sqrMagnitude;
if (distanceSqure < maxDistance * maxDistance)
{
pointInPath.MoveNext();
}
}
public void moveToTarget(GameObject target)
{
enemy.SetDestination(target.transform.position);
}
}
I decided to make my own A*. When I enable this part of the code Unity crashes.
if (Physics2D.Raycast(transform.position, a - new Vector2(current.x, current.y), 1, mask))
{
print(i);
continue;
}
There are no other objects than walls that would enable the Raycast.
The code probably enters an infinite loop, but I have no idea how because it works fine if i disable raycasts.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEditor;
using UnityEngine;
public class Star : MonoBehaviour
{
private int x, y;
private int nextX, nextY;
public Vector2 targetNode;
private Vector2 nextNode;
private List<Node> path = null;
LayerMask mask;
Bounds area;
private bool moving;
private bool check;
public float timeStart;
public Vector3 startPos;
public float speed = 1f;
float u;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
mask = LayerMask.GetMask("Default");
}
void FixedUpdate()
{
if (!moving)
{
Move();
}
else
MoveTo(speed);
}
private void Move()
{
area = new Bounds(transform.position, new Vector3(100, 100));
int playerX = (int)Mathf.Round(Player.x);
int playerY = (int)Mathf.Round(Player.y);
Vector2 start = new Vector2((int)transform.position.x, (int)transform.position.y);
Vector2 destination = new Vector2(playerX, playerY);
if (getDistance(start, destination) > 1f)
path = findPath(start, destination);
else
path = null;
nextX = 0;
nextY = 0;
if (path != null)
{
if (path.Count > 0)
{
nextNode = new Vector2(path[path.Count - 1].x, path[path.Count - 1].y);
if (x < nextNode.x) nextX++;
if (x > nextNode.x) nextX--;
if (y < nextNode.y) nextY++;
if (y > nextNode.y) nextY--;
}
}
if (nextX != 0 || nextY != 0)
{
Move(nextX, nextY);
}
}
public List<Node> findPath(Vector2 start, Vector2 goal)
{
x = (int)start.x;
y = (int)start.y;
List<Node> openList = new List<Node>();
List<Node> closedList = new List<Node>();
Node current = new Node(x, y, null, 0, getDistance(start, goal));
openList.Add(current);
while (openList.Count > 0)
{
openList.Sort();
current = openList[0];
if (new Vector2(current.x, current.y).Equals(goal))
{
List<Node> path = new List<Node>();
while (current.parent != null)
{
path.Add(current);
current = current.parent;
}
openList.Clear();
closedList.Clear();
return path;
}
openList.Remove(current);
closedList.Add(current);
for (int i = 0; i < 9; i++)
{
if (i == 4/* || i == 0 || i == 2 || i == 6 || i == 8*/) continue;
int x = current.x;
int y = current.y;
int xi = (i % 3) - 1; // -1, 0, 1
int yi = (i / 3) - 1;
Vector2 a = new Vector2(x + xi, y + yi);
if (Physics2D.Raycast(transform.position, a - new Vector2(current.x, current.y), 1, mask))
{
print(i);
continue;
}
double gCost = current.gCost + (getDistance(new Vector2(current.x, current.y), a));
double hCost = getDistance(a, goal);
Node node = new Node((int)a.x, (int)a.y, current, gCost, hCost); // store the node
if (!vecInList(openList, a)) openList.Add(node);
}
}
closedList.Clear();
return null;
}
private double getDistance(Vector2 tile, Vector2 goal)
{
int dx = (int)(tile.x - goal.x);
int dy = (int)(tile.y - goal.y);
return Mathf.Sqrt((dx * dx) + (dy * dy));
}
private bool vecInList(List<Node> list, Vector2 vector)
{
foreach (Node n in list)
{
Vector2 tile2 = new Vector2(n.x, n.y);
if (tile2.Equals(vector)) return true;
}
return false;
}
public void Move(int x, int y)
{
targetNode = transform.position + new Vector3(x, y);
if (area.Contains(new Vector3(Player.x, Player.y)) && (moving == false))
{
moving = true;
check = true;
}
}
public void MoveTo(float speed)
{
if (check)
{
check = false;
moving = true;
timeStart = Time.time;
startPos = transform.position;
}
if (moving)
{
u = (Time.time - timeStart) / (1 / speed);
if (u >= 1)
{
u = 1;
moving = false;
}
//transform.position = (1 - u) * (Vector2)startPos + u * targetNode;
rb.MovePosition((1 - u) * (Vector2)startPos + u * targetNode);
}
}
}
Edit: got this to work thanks to Yuri's comment. Changed to:
if (Physics2D.Raycast(new Vector2(current.x, current.y), a - new Vector2(current.x, current.y), 1, mask))
I was checking from the start position instead of the last position in the nodes.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateObjects : MonoBehaviour
{
public GameObject[] objectsToRotate;
public Transform to;
public float speed = 0.1f;
public Vector3 spinDirection;
public bool useMouse = false;
public bool useQuaternion = false;
public bool nonstopSpin = false;
Ray ray;
RaycastHit hit;
RaycastHit[] hits;
GameObject[] myLines;
LineRenderer lr;
// Use this for initialization
void Start()
{
myLines = new GameObject[objectsToRotate.Length];
GenerateLinerenderer();
if (objectsToRotate.Length > 0)
{
if (useQuaternion == true)
{
for (int i = 0; i < objectsToRotate.Length; i++)
{
objectsToRotate[i].transform.rotation = Quaternion.Lerp(objectsToRotate[i].transform.rotation, to.rotation, Time.time * speed);
}
}
}
}
// Update is called once per frame
void Update()
{
if (objectsToRotate.Length > 0)
{
for (int i = 0; i < objectsToRotate.Length; i++)
{
/*ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Debug.DrawLine(Input.mousePosition, hit.transform.position, Color.red);
if (hit.collider.name == objectsToRotate[i].name)
objectsToRotate[i].transform.Rotate(1, 1, 1);
}*/
hits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), 100.0f);
for (int x = 0; x < hits.Length; x++)
{
RaycastHit hit = hits[x];
if (hit.collider.name == objectsToRotate[i].name)
{
objectsToRotate[i].transform.Rotate(1, 1, 1);
Debug.DrawLine(Input.mousePosition, hit.transform.position, Color.red);
SpawnLineGenerator(Input.mousePosition, hit.transform.position);
}
}
if (useMouse == true)
{
if (Input.GetMouseButton(0))
{
Rotate(i);
}
}
else
{
Rotate(i);
}
}
}
}
private void Rotate(int i)
{
if (useQuaternion == true)
{
objectsToRotate[i].transform.rotation = Quaternion.Lerp(objectsToRotate[i].transform.rotation, to.rotation, Time.time * speed);
}
if (nonstopSpin == true)
{
objectsToRotate[i].transform.Rotate(1, 1, 1);
}
}
void SpawnLineGenerator(Vector3 start, Vector3 end)
{
lr.SetPosition(0, start);
lr.SetPosition(1, end);
}
private void GenerateLinerenderer()
{
for (int i = 0; i < myLines.Length; i++)
{
myLines[i] = new GameObject();
myLines[i].name = "FrameLine";
myLines[i].AddComponent<LineRenderer>();
lr = myLines[i].GetComponent<LineRenderer>();
lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
lr.startColor = Color.green;
lr.useWorldSpace = false;
lr.endColor = Color.green;
lr.startWidth = 0.1f;//0.03f;
lr.endWidth = 0.1f;//0.03f;
lr.numCapVertices = 5;
}
}
}
For example if I hit with the ray in some objects at the same time it will draw multiple red lines from the mouse position to the hit objects using debug:
Debug.DrawLine(Input.mousePosition, hit.transform.position, Color.red);
Same result I want to do with the linerenderer. But it's drawing one green line even if I hit multiple objects.
I would like to know how can I modify my code for my enemy to be able to move automatically in my grid ?
This is my code below :
[using System.Collections;
using UnityEngine;
class Enemy : MonoBehaviour {
private float moveSpeed = 50f;
private float gridSize = 18f;
private enum Orientation {
Horizontal,
Vertical
};
private Orientation gridOrientation = Orientation.Vertical;
private bool allowDiagonals = false;
private bool correctDiagonalSpeed = true;
private Vector2 input;
private bool isMoving = false;
private Vector3 startPosition;
private Vector3 endPosition;
private float t;
private float factor;
public void Update() {
if (!isMoving) {
input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if (!allowDiagonals) {
if (Mathf.Abs(input.x) > Mathf.Abs(input.y)) {
input.y = 0;
} else {
input.x = 0;
}
}
if (input != Vector2.zero) {
StartCoroutine(move(transform));
}
}
}
public IEnumerator move (Transform transform)
{
isMoving = true;
startPosition = transform.position;
t = 0;
if (gridOrientation == Orientation.Horizontal) {
endPosition = new Vector3 (startPosition.x + System.Math.Sign (input.x) * gridSize,
startPosition.y, startPosition.z + System.Math.Sign (input.y) * gridSize);
} else {
endPosition = new Vector3 (startPosition.x + System.Math.Sign (input.x) * gridSize,
startPosition.y + System.Math.Sign (input.y) * gridSize, startPosition.z);
}
if (allowDiagonals && correctDiagonalSpeed && input.x != 0 && input.y != 0) {
factor = 0.7071f;
} else {
factor = 1f;
}
while (t < 1f) {
t += Time.deltaTime * (moveSpeed / gridSize) * factor;
transform.position = Vector3.Lerp (startPosition, endPosition, t);
yield return null;
}
isMoving = false;
yield return 0;
}
}
]