--Originally published at Mental Droppings of a Tired Student
https://unity3d.com/es/learn/tutorials/projects/roll-ball-tutorial/moving-player?playlist=17141
http://answers.unity3d.com/questions/190837/make-a-rigidbody-jump-global-up.html
http://answers.unity3d.com/questions/1105218/how-to-make-an-object-shoot-a-projectile.html
https://unity3d.com/es/learn/tutorials/projects/space-shooter/shooting-shots?playlist=17147
http://answers.unity3d.com/questions/156989/how-get-position-from-a-game-object.html
https://unity3d.com/es/learn/tutorials/projects/space-shooter-tutorial/boundary?playlist=17147
http://halo56786532.blogspot.mx/2016/10/player-controller-using-unityengine.html
Player Controller
*Add Rigidbody, freeze rotation, speed 10, jump 7, fire rate 0.25, add projectile prefab and shotspawn
*Shotspawn is an empty object, set its position to where you would like the shots to spawn, make it a child of the player.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
private Rigidbody rb;
public float speed;
public float jumpSpeed;
public GameObject projectile;
public Transform ShotSpawn;
public float fireRate;
private float nextFire;
// Use this for initialization
void Start () {
rb = GetComponent();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift) && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(projectile, ShotSpawn.position, ShotSpawn.rotation);
}
}
// Update is called once per frame
void FixedUpdate () {
float h = Input.GetAxis(“Horizontal”);
float v = Input.GetAxis(“Vertical”);
Vector3 movement = new Vector3(h, 0, v);
rb.AddForce(movement * speed);
//character jump
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(new Vector3(0, jumpSpeed, 0), ForceMode.Impulse);
}
}
}
Camera controller
*Add to camera, add player
using UnityEngine;
using System.Collections;
public class cameracontroller : MonoBehaviour {
public GameObject player;
private Vector3 offset;
// Use this for initialization
void Start () {
offset = transform.position – player.transform.position;
}
// Update is called once per frame
void LateUpdate () {
transform.position = player.transform.position + offset;
}
}
Shooting
*Make projectile prefab, add this script and rigidbody with gravity, then add projectile to player object, mass 0.25, angular drag 0.05
using UnityEngine;
using System.Collections;
public class shooting : MonoBehaviour {
//public float speed;
public GameObject projectile;
// Use this for initialization
void Start ()
//Vector3 projectileSpeed = new Vector3 (1,1,1) * speed;
projectile.GetComponent().AddForce(transform.forward * 500);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag(“Enemy”))
{
Destroy(other.gameObject);
}
}
}
Enemy 1 (Jumping)
using UnityEngine;
using System.Collections;
public class Enemy1 : MonoBehaviour
{
public float speed;
public float counterTime = 0;
// Update is called once per frame
void Update()
{
counterTime += (Time.deltaTime * speed) + 100;
float x = Mathf.Cos(counterTime);
transform.position = new Vector3(-6.64f, 4.06f + x, 7.3f);
}
}
Enemy 2 (Patrolling with gizmos)
Size 2, add nodes/elements for patrolling, threshold = 1
using UnityEngine;
using System.Collections;
public class Enemy2 : MonoBehaviour
{
public Transform[] checkpoints;
private int current;
public float threshold;
// Use this for initialization
void Start()
{
current = 0;
DontDestroyOnLoad(this.gameObject);
}
// Update is called once per frame
void Update()
{
transform.LookAt(checkpoints[current]);
transform.Translate(transform.forward * Time.deltaTime * 2, Space.World);
float distance = Vector3.Distance(transform.position, checkpoints[current].position);
if (distance < threshold)
{
//arrived to checkpoint
current++;
if (current == checkpoints.Length)
{
current = 1;
transform.position = checkpoints[0].position;
}
}
}
}
Node Class
*Node is a prefab, you add them to the scene on the points you want the enemy patrolling
using UnityEngine;
using System.Collections;
public class Node : MonoBehaviour
{
void OnDrawGizmos()
{
Gizmos.color = Color.green;
Gizmos.DrawSphere(transform.position, 1);
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawSphere(transform.position, 1);
}
}
Start/Load scene
using UnityEngine;
using System.Collections;
public class StartGame : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKeyUp(KeyCode.Return))
{
UnityEngine.SceneManagement.SceneManager.LoadScene(“Scene 2”);
}
}
}
Boundary
*Make a cube that eglobes the entire game, deselect mesh renderer
*Select is trigger
*Add script
using UnityEngine;
using System.Collections;
public class Boundary : MonoBehaviour {
void OnTriggerExit(Collider other)
{
Destroy(other.gameObject);
}
}
Part 2
Pathfinding
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Pathfinding {
// breadth
// a lo ancho
public static List BreadthwiseSearch(Node start, Node end){
Queue working = new Queue ();
List visited = new List ();
start.history = new List ();
working.Enqueue (start);
visited.Add (start);
while(working.Count > 0){
Node currentNode = working.Dequeue ();
if (currentNode == end) {
// this is the end!
List result = currentNode.history;
result.Add (currentNode);
return result;
} else {
for (int i = 0; i < currentNode.neighbors.Length; i++) {
Node currentChild = currentNode.neighbors[i];
// check if it hasn’t been visited
if(!visited.Contains(currentChild)){
// update history
currentChild.history = new List(currentNode.history);
currentChild.history.Add (currentNode);
// add to queue
working.Enqueue(currentChild);
// add to visited
visited.Add(currentChild);
}
}
}
}
return null;
}
public static List DepthwiseSearch(Node start, Node end){
List visited = new List ();
Stack stack = new Stack ();
start.history = new List ();
visited.Add (start);
stack.Push (start);
while(stack.Count > 0){
Node current = stack.Pop ();
if (current == end) {
// found the final node!
List result = current.history;
result.Add (current);
return result;
} else {
// not the final node
for(int i = 0; i < current.neighbors.Length; i++) {
Node currentNeighbor = current.neighbors [i];
if(!visited.Contains(currentNeighbor)) {
visited.Add (currentNeighbor);
stack.Push (currentNeighbor);
currentNeighbor.history = new List (current.history);
currentNeighbor.history.Add (current);
}
}
}
}
return null;
}
public static List AStar(Node start, Node end){
List visited = new List ();
List work = new List ();
visited.Add (start);
work.Add (start);
start.history = new List ();
start.g = 0;
start.f = start.g +
Vector3.Distance (start.transform.position, end.transform.position);
while (work.Count > 0) {
// get the best one (the smallest f)
int smallest = 0;
for(int i = 0; i < work.Count; i++) {
if(work[i].f < work[smallest].f){
smallest = i;
}
}
Node smallestNode = work[smallest];
// remove from working list
work.Remove(smallestNode);
if (smallestNode == end) {
// found
List result = new List(smallestNode.history);
result.Add (smallestNode);
return result;
} else {
// not found
for(int i = 0; i < smallestNode.neighbors.Length; i++){
Node currentChild = smallestNode.neighbors[i];
if (!visited.Contains (currentChild)) {
visited.Add (currentChild);
work.Add (currentChild);
// f, g, h
currentChild.g = smallestNode.g +
Vector3.Distance (currentChild.transform.position,
smallestNode.transform.position);
float h = Vector3.Distance (currentChild.transform.position,
end.transform.position);
currentChild.f = currentChild.g + h;
// update history
currentChild.history = new List(smallestNode.history);
currentChild.history.Add (smallestNode);
}
}
}
}
return null;
}
}
PathTest
*Your capsule/player should have this script
*Add start, end nodes and threshold 0.2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PathTest : MonoBehaviour {
public Node start;
public Node end;
public float threshold;
private List myPath;
private int currentNode;
// Use this for initialization
void Start () {
Debug.Log (“********************************* DEPTHWISE”);
List path = Pathfinding.DepthwiseSearch (start, end);
for (int i = 0; i < path.Count; i++) {
Debug.Log (path [i].transform.name);
}
Debug.Log (“********************************* BREADTHWISE”);
path = Pathfinding.BreadthwiseSearch (start, end);
for (int i = 0; i < path.Count; i++) {
Debug.Log (path [i].transform.name);
}
Debug.Log (“********************************* A*”);
path = Pathfinding.AStar(start, end);
for (int i = 0; i < path.Count; i++) {
Debug.Log (path [i].transform.name);
}
myPath = new List (path);
currentNode = 0;
}
// Update is called once per frame
void Update () {
// 2 things here ONLY
// – motion (as smooth as possible)
// – input (as responsive as possible)
transform.LookAt (myPath [currentNode].transform);
transform.Translate (transform.forward * 5 * Time.deltaTime, Space.World);
// this is not OK.
float distance = Vector3.Distance (myPath [currentNode].transform.position,
transform.position);
if(distance < threshold){
currentNode++;
currentNode %= myPath.Count;
}
}
}
Node
*Create empty object named node
*Add node script
*Add its neighbors
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Node : MonoBehaviour {
public Node[] neighbors;
public List history;
public float f, g;
void OnDrawGizmos(){
Gizmos.color = Color.green;
for (int i = 0; i < neighbors.Length; i++) {
Gizmos.DrawLine (transform.position, neighbors [i].transform.position);
}
}
}
Chasing Enemy
using UnityEngine;
using System.Collections;
public class Enemy_Movement : MonoBehaviour
{
// Use this for initialization
float time_counter = 0;
float MoveSpeed = 4;
float MinDist = 5;
//float MaxDist = 10;
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.LookAt(GameObject.Find(“Player”).transform.position);
if (Vector3.Distance(transform.position, GameObject.Find(“Player”).transform.position) >= MinDist)
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
/* if (Vector3.Distance(transform.position, GameObject.Find(“Player”).transform.position) <= MinDist)
{
MoveSpeed += 4;
}*/
}
}
}
Camera Rotate
*Add this to the player
using UnityEngine;
using System.Collections;
[AddComponentMenu(“Camera-Control/Mouse Look”)]
public class CameraRotate : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
void Update()
{
if (axes == RotationAxes.MouseXAndY)
{
float rotationX = transform.localEulerAngles.y + Input.GetAxis(“Mouse X”) * sensitivityX;
transform.localEulerAngles = new Vector3(0, rotationX, 0);
}
else if (axes == RotationAxes.MouseX)
{
transform.Rotate(0, Input.GetAxis(“Mouse X”) * sensitivityX, 0);
}
}
void Start()
{
}
}
Raycast (G4 code)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PathTest : MonoBehaviour
{
public Node start;
public Node end;
public Node over;
public Node clicked;
GameObject clickedNode = GameObject.FindGameObjectWithTag(“Node 0”);
public float threshold;
private List<Node> myPath;
private List<Node> subPath;
private int currentNode;
private int subpathCurrentNode;
// Use this for initialization
void Start()
{
Debug.Log(“********************************* DEPTHWISE”);
List<Node> path = Pathfinding.DepthwiseSearch(start, end);
myPath = new List<Node>(path);
currentNode = 0;
subpathCurrentNode = 0;
}
// Update is called once per frame
void Update()
{
// 2 things here ONLY
// – motion (as smooth as possible)
// – input (as responsive as possible)
transform.LookAt(myPath[currentNode].transform);
transform.Translate(transform.forward * 5 * Time.deltaTime, Space.World);
// this is not OK.
float distance = Vector3.Distance(myPath[currentNode].transform.position,
transform.position);
if (distance < threshold)
{
currentNode++;
currentNode %= myPath.Count;
}
}
void FixedUpdate()
{
if (Input.GetMouseButtonUp(0))
{
Debug.Log(“clicked”);
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(mouseRay, out hit))
{
Debug.Log(“raycast”);
Debug.Log(“you hit: ” + hit.collider.gameObject.name);
clickedNode = hit.collider.gameObject;
clicked = clickedNode.GetComponent<Node>();
}
subPath = Pathfinding.DepthwiseSearch(clicked, myPath[currentNode]);
transform.LookAt(subPath[subpathCurrentNode].transform);
transform.Translate(transform.forward * 5 * Time.deltaTime, Space.World);
// this is not OK.
float dist = Vector3.Distance(subPath[subpathCurrentNode].transform.position,
transform.position);
if (dist < threshold)
{
subpathCurrentNode++;
subpathCurrentNode %= subPath.Count;
}
}
}
}