I use Unity 5.1.1 on a Win 64 bit machine, more than capable to run what i'm creating of games. In the making of a 2D sidescroller, i found my character sometimes doesn't jump when prompted. Here is the code:
public float speed;
public float MomentAcc;
private float moveVertical;
private float score;
private float scoreP;
public GameObject wallRight;
public GUIText scoreText;
public bool touching;
void Start() {
MomentAcc = 10;
score = 0;
}
//Jump limiter
void OnCollisionStay2D() {
touching = true;
}
void OnCollisionExit2D() {
touching = false;
}
void Update() {
if (Input.GetKeyDown(KeyCode.W) && touching == true || Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began && touching == true) {
moveVertical = 29;
} else {
moveVertical = 0;
}
}
void FixedUpdate () {
scoreP = GameObject.Find ("Ball").GetComponent<Rigidbody2D> ().position.x + 11;
if(scoreP > score) {
score = score + 10;
}
UpdateScore ();
if(GetComponent<Death>().startGame == true) {
float moveHorizontal = 5;
Vector2 forward = new Vector2 (moveHorizontal, 0);
Vector2 jump = new Vector2 (0, moveVertical);
//Maxspeed limit
GetComponent<Rigidbody2D> ().AddForce (moveVertical * jump);
speed = moveHorizontal * MomentAcc * Time.deltaTime * 5;
if (GetComponent<Rigidbody2D> ().velocity.x < 7.000000) {
GetComponent<Rigidbody2D> ().AddForce (Vector2.right * speed);
if(GameObject.Find ("wallRight").GetComponent<wallRightScript>().wallJumpRight == true) {
GetComponent<Rigidbody2D> ().AddForce (new Vector2 (-420, 300));
}
if(GameObject.Find ("wallLeft").GetComponent<wallLeftScript>().wallJumpLeft == true) {
GetComponent<Rigidbody2D> ().AddForce (new Vector2(420, 150));
}
}
}
}
void UpdateScore() {
scoreText.text = "Score: " + (score );
}
}
(Sidenote: wallLeft/wallRight are for walljumping)
Here is your problem!
you are using Input.GetKeyDown(KeyCode.W) && touching == true in this case your jump is dependent on touching variable which can be false at the time when you press the "W" key. You are using rigidbody you cannot expect it to always colliding with ground when it is being dragged in horizontal. So you may need to change your implementation for ground check.
This Tutorial is good for learning about 2D character.
And one more advice! try to store reference of objects/components in some variables to access them easily. Using GetComponent<>/GameObject.Find() in Update()/FixedUpdate() is not efficient so not a good practice.
Related
Working on a platformer where as the player moves over an energy orb, they can choose to fuel either a double jump or a dash. No errors according to unity, but when I press the corresponding keys for my double jump and dash, neither work. Simply nothing happens. Oh and btw my character randomly freezes and I have to tap the movement key again to get him to continue moving this is also a new issue so may be related. I am very new to all this.
public class playerMovement : MonoBehaviour
{
[SerializeField] private float speed;
[SerializeField] int dashEnergy = 1;
[SerializeField] int doubleJumpEnergy = 1;
private Rigidbody2D body;
private Animator anim;
private int jumpCount;
private void Awake()
{
body = GetComponent<Rigidbody2D>();
}
private void Update()
{
//Left-Right Movement
float horizontalInput = Input.GetAxis("Horizontal");
if(Input.GetKey(KeyCode.Space) && jumpCount == 0)
{
jump();
jumpCount += 1;
}
body.velocity = new Vector2(horizontalInput*speed, body.velocity.y);
//Character Turns Towards Movement Direction
if (horizontalInput > 0.01f)
transform.localScale = new Vector3(-5, 5, 5);
if (horizontalInput < -0.01f)
transform.localScale = new Vector3(5,5,5);
//Dash & doubleJump
void doubleJump()
{
if(Input.GetKey(KeyCode.Space)&&jumpCount==1 && doubleJumpEnergy==1)
{
jump();
doubleJumpEnergy -= 1;
}
}
void Dash()
{
if(Input.GetKey(KeyCode.LeftShift) && dashEnergy == 1)
{
body.velocity = new Vector2(horizontalInput*speed*60, body.velocity.y);
dashEnergy -=1;
}
}
}
public void jump()
{
body.velocity = new Vector2(body.velocity.x, speed);
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag == "EnergyBubble" && Input.GetKey(KeyCode.V))
{
dashEnergy += 1;
}
if(collision.gameObject.tag == "EnergyBubble" && Input.GetKey(KeyCode.C))
{
doubleJumpEnergy += 1;
}
if (collision.gameObject.tag == "Ground")
{
jumpCount=0;
}
}
}
Firstly, all physics operations should be used from fixedUpdate method, for example:
void FixedUpdate()
{
if (Input.GetButtonDown("Space"))
rb.velocity = new Vector2(0, 10);
}
It's needs for smoothly physics movement.
Or call your own method from it:
void FixedUpdate()
{
if (Input.GetButtonDown("Space"))
jump();
}
Then you have a bug in condition check statements, you have to use:
//Dash & doubleJump
if (Input.GetKey(KeyCode.Space) && jumpCount == 1 && doubleJumpEnergy >= 1)
{
body.velocity = new Vector2(0, 2);
doubleJumpEnergy -= 1;
}
if (Input.GetKey(KeyCode.LeftShift) && dashEnergy >= 1)
{
body.velocity = new Vector2(horizontalInput * speed * 60, body.velocity.y);
dashEnergy -= 1;
}
Problem with a condition check statements, you need to have ">=" operator: dashEnergy >= 1 and doubleJumpEnergy >= 1 instead ==
I'm really new to Unity 3d and I'm trying to make a respawn with my character. It seems that the answer is really easy but I cannot see why my code is not working. If this is a duplicate, let me know.
public Vector3 PointSpawn;
void Start()
{
PointSpawn = gameObject.transform.position;
}
void Update()
{
if (gameObject.transform.position.y < 10)
{
gameObject.transform.position = PointSpawn; // This doesn't work
// gameObject.transform.LookAt(PointSpawn); ---> This DOES work ok
}
}
Parallel Script
public float HorizontalMove;
public float VerticalMove;
private Vector3 playerInput;
public CharacterController player;
public float MoveSpeed;
private Vector3 movePlayer;
public float gravity = 9.8f;
public float fallVelocity;
public float JumpForce;
public bool DoubleJump = false;
public Camera mainCamera;
private Vector3 camForward;
private Vector3 camRight;
void Start()
{
player = GetComponent<CharacterController>();
}
void Update()
{
HorizontalMove = Input.GetAxis("Horizontal");
VerticalMove = Input.GetAxis("Vertical");
playerInput = new Vector3(HorizontalMove, 0, VerticalMove);
playerInput = Vector3.ClampMagnitude(playerInput, 1);
CamDirection();
movePlayer = playerInput.x * camRight + playerInput.z * camForward;
movePlayer = movePlayer * MoveSpeed;
player.transform.LookAt(player.transform.position + movePlayer);
setGravity();
PlayerSkills();
player.Move(movePlayer * Time.deltaTime );
}
void CamDirection()
{
camForward = mainCamera.transform.forward;
camRight = mainCamera.transform.right;
camForward.y = 0;
camRight.y = 0;
camForward = camForward.normalized;
camRight = camRight.normalized;
}
void PlayerSkills()
{
if (player.isGrounded && Input.GetButtonDown("Jump"))
{
fallVelocity = JumpForce;
movePlayer.y = fallVelocity;
DoubleJump = true;
}
else if (player.isGrounded == false && Input.GetButtonDown("Jump") && DoubleJump == true)
{
fallVelocity = JumpForce *2;
movePlayer.y = fallVelocity;
DoubleJump = false;
}
}
void setGravity()
{
if (player.isGrounded)
{
fallVelocity = -gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
else
{
fallVelocity -= gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
}
Thanks in advance!
Just so the answer to the question is not in the comments:
The original problem is that the assignment gameObject.transform.position = PointSpawn appeared to do nothing. As the line is written properly, the position of this gameObject, must have been getting overwritten elsewhere.
With the addition of OP's movement script, the position of the player was getting overwritten in the movement's Update function. As the other assignment was being done in Update, the call order was not guaranteed to work as intended. The fix is either to assure that the movement Update is run not the frame of the new position assignment or to move the conditional and the assignment to a function that always runs after Update regardless of script execution order, LateUpdate.
I am new to Unity and I am using the following CharacterController for my character. Everything is working well, except that sometimes the character jumps and sometimes it doesn't when I hit the spacebar. I used Debog.Log using Raycast to check if my character is grounded, and the result was True. So what is preventing my character from jumping whenever I hit the key?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class RPGMovement : MonoBehaviour
{
public float ForwardSpeed = 8f;
public float BackwardSpeed = 4f;
public float StrafeSpeed = 5f;
public float RotateSpeed = 110f;
CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
Vector3 playerVelocity;
private bool groundedPlayer;
private float jumpHeight = 0.9f;
private float gravityValue = -20.81f;
void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Animator = GetComponent<Animator>();
m_PhotonView = GetComponent<PhotonView>();
m_TransformView = GetComponent<PhotonTransformView>();
}
void Update()
{
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
void UpdateAnimation()
{
Vector3 movementVector = transform.position - m_LastPosition;
float speed = Vector3.Dot(movementVector.normalized, transform.forward);
float direction = Vector3.Dot(movementVector.normalized, transform.right);
if (Mathf.Abs(speed) < 0.2f)
{
speed = 0f;
}
if (speed > 0.6f)
{
speed = 1f;
direction = 0f;
}
if (speed >= 0f)
{
if (Mathf.Abs(direction) > 0.7f)
{
speed = 1f;
}
}
m_AnimatorSpeed = Mathf.MoveTowards(m_AnimatorSpeed, speed, Time.deltaTime * 5f);
m_Animator.SetFloat("Speed", m_AnimatorSpeed);
m_Animator.SetFloat("Direction", direction);
m_LastPosition = transform.position;
}
void ResetSpeedValues()
{
m_CurrentMovement = Vector3.zero;
m_CurrentTurnSpeed = 0;
}
void ApplySynchronizedValues()
{
m_TransformView.SetSynchronizedValues(m_CurrentMovement, m_CurrentTurnSpeed);
}
void MoveCharacterController()
{
m_CharacterController.Move(m_CurrentMovement * Time.deltaTime);
}
void UpdateForwardMovement()
{
if (Input.GetKey(KeyCode.W) || Input.GetAxisRaw("Vertical") > 0.1f)
{
m_CurrentMovement = transform.forward * ForwardSpeed;
}
}
void UpdateBackwardMovement()
{
if (Input.GetKey(KeyCode.S) || Input.GetAxisRaw("Vertical") < -0.1f)
{
m_CurrentMovement = -transform.forward * BackwardSpeed;
}
}
void UpdateStrafeMovement()
{
if (Input.GetKey(KeyCode.Q) == true)
{
m_CurrentMovement = -transform.right * StrafeSpeed;
}
if (Input.GetKey(KeyCode.E) == true)
{
m_CurrentMovement = transform.right * StrafeSpeed;
}
}
void UpdateRotateMovement()
{
if (Input.GetKey(KeyCode.A) || Input.GetAxisRaw("Horizontal") < -0.1f)
{
m_CurrentTurnSpeed = -RotateSpeed;
transform.Rotate(0.0f, -RotateSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.D) || Input.GetAxisRaw("Horizontal") > 0.1f)
{
m_CurrentTurnSpeed = RotateSpeed;
transform.Rotate(0.0f, RotateSpeed * Time.deltaTime, 0.0f);
}
}
void UpdateJump()
{
groundedPlayer = m_CharacterController.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
m_Animator.SetTrigger("Jump");
print("Jumping Now");
}
playerVelocity.y += gravityValue * Time.deltaTime;
m_CharacterController.Move(playerVelocity * Time.deltaTime);
}
}
Best guess is that "m_PhotonView.isMine" is not returning true on the frames where you're missing input. It only checks jump input for that frame, so if the last frame you pressed it but jumping wasn't checked then that input is lost forever. First test this. Change the update code to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Jump was pressed at {Time.time}"); }
if (m_PhotonView.isMine == true)
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Attempting Jump at {Time.time}"); }
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
Then play the game and jump a bunch. The first debug log line should happen every time you click the spacebar no matter what. The second debug line would only happen if physics are calculated that frame. Both have times attached. Keep jumping until the jump doesn't work. If that jump only produces the first debug log and not the second, then I am correct and that is your issue.
If so, then it's an easy fix. Add a new bool variable called "jumpInput". Whenever you check if jump was pressed, instead check if "jumpInput" is true. Then, change update to this:
void Update()
{
if (Input.GetButtonDown("Jump")) { jumpInput = true; }
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
jumpInput = false;
}
UpdateAnimation();
}
This way if you pressed jump, it's set to true... but it's only set to false after physics are done. So if you press jump on frame 20 and physics are somehow not calculated until frame 25, it'll still know that you pressed jump at some point and thus execute it. If you're using networking, you might want to also have another variable that's what frame jump was pressed. That way you can figure out how many frames it's been since input and compensate for missed time in the jump if necessary.
I am moving an object that consists of two cubes: left and right. These cubes are randomly generated on the y-axis upwards.
I am able to move them left and right with no problem, however, when I move one of the cubes left or right they all move.
How am I able to only move one of the cubes when touched only left or right rather than all of them? Here is my code below:
Generate cubes code:
public Transform block;
public Transform player;
private float objectSpawnedTo = 5.0f;
public static float distanceBetweenObjects = 5.0f;
private float nextCheck = 0.0f;
private ArrayList objects = new ArrayList();
void Start () {
maintenance(0.0f);
}
void Update () {
float playerX = player.position.y;
if(playerX > nextCheck)
{
maintenance(playerX);
}
}
private void maintenance(float playerX)
{
nextCheck = playerX + 30;
for (int i = objects.Count-1; i >= 0; i--)
{
Transform blck = (Transform)objects[i];
if(blck.position.y < (transform.position.y - 30))
{
Destroy(blck.gameObject);
objects.RemoveAt(i);
}
}
spawnObjects(5);
}
private void spawnObjects(int howMany)
{
float spawnX = objectSpawnedTo;
for(int i = 0; i<howMany; i++)
{
Vector3 pos = new Vector3(-3.5f,spawnX, 0);
//float firstRandom = Random.Range(-6.0f, 1.0f);
Transform blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale+=new Vector3(firstRandom*2,0,0);
objects.Add(blck);
//pos = new Vector3(0,spawnX, 0);
//blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale +=new Vector3((8.6f-firstRandom)*2,0,0);
//objects.Add(blck);
spawnX = spawnX + distanceBetweenObjects;
}
objectSpawnedTo = spawnX;
}
}
Cube-control code:
public float speed = 5;
// Use this for initialization
void Start () {
}
void Update() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
}
The problem is your cube-control code has no condition in it about which cube is selected : you simply wait for Input.touchCount to be > 0 and then move the cube. So all the cube having this script will move.
I think what you need to do is a raycast to check which cube has been "touched" and then only move it if raycast is successful :
[SerializeField]
private float speed = 0.5f;
private int MAX_TOUCH_COUNT = 5;
private bool[] touched;
protected void Start()
{
touched = new bool[MAX_TOUCH_COUNT];
}
void Update()
{
if (Input.touchCount > 0)
{
for(int i = 0; i < (Input.touchCount <= MAX_TOUCH_COUNT ? Input.touchCount : MAX_TOUCH_COUNT); i++)
{
if(touched[i] && Input.GetTouch(i).phase == TouchPhase.Ended)
{
touched[i] = false;
}
else if (!touched[i] && Input.GetTouch(i).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.transform.GetComponentInChildren<*YOUR_CUBE_CONTROL_CLASS_NAME*>() == this)
{
touched[i] = true;
}
}
}
else if (touched[i] && Input.GetTouch(i).phase == TouchPhase.Moved)
{
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(i).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
else
{
touched = false;
}
}
}
Hope this help,
How would one create time as distance between two objects?
I have a player and an object that has to come towards the player with a speed of 1second, 0.85 seconds, 0.7 seconds and so on. However, I'm unaware of doing this. I have a moving 2D map with the speed of -4 to give the illusion of running upwards:
The red triangle on the picture is the object that needs come towards the player, it also has a speed of -4. I created this motion using Time.deltaTime so I would work in realtime. With this logic I believed I had to put the object 4F away from the player to create a 1second interval (desiredSeconds * speed).
PlayerScript
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour {
public GameObject obstacle;
public GameObject player;
public float playerDimensionY;
public bool isRight = true;
public bool inAir = false;
public bool mouseClicked = false;
public int flyingSpeed;
float timeStamp1;
float timeStamp2;
bool runOnce = false;
// Use this for initialization
void Start () {
Vector2 sprite_size = GetComponent<SpriteRenderer> ().sprite.rect.size;
Vector2 spriteScale = transform.localScale;
float sizeAndScaleY = sprite_size.y * spriteScale.y;
float player_local_sprite_sizeY = (sizeAndScaleY / GetComponent<SpriteRenderer> ().sprite.pixelsPerUnit) * 0.5F;
playerDimensionY = player_local_sprite_sizeY;
}
// Update is called once per frame
void Update () {
if (isRight == true && mouseClicked == true) {
transform.position += Vector3.right * flyingSpeed * Time.deltaTime;
} else if (isRight == false && mouseClicked == true) {
transform.position += Vector3.left * flyingSpeed * Time.deltaTime;
}
if (Input.GetMouseButtonDown (0) && inAir == false) {
mouseClicked = true;
inAir = true;
if (isRight == true) {
isRight = false;
} else if (isRight == false) {
isRight = true;
}
}
if (GameObject.FindWithTag ("Obstacle") != null && runOnce == false) {
Debug.Log (string.Format("Spawn time: " + timeStamp1));
runOnce = true;
}
timeStamp1 = Time.fixedTime;
timeStamp2 = Time.fixedTime;
}
void OnCollisionEnter2D(Collision2D coll) {
inAir = false;
mouseClicked = false;
}
void OnTriggerEnter2D(Collider2D collTrig) {
Debug.Log (string.Format ("Trigger time: " + timeStamp2));
}
}
ObstacleScript:
using UnityEngine;
using System.Collections;
public class ObstacleScript : MonoBehaviour {
public float constantSpeed;
public float destroyTime;
public float obstacleDimensionY;
private float selfDestroyTime;
// Use this for initialization
void Awake () {
selfDestroyTime = Time.time + destroyTime;
}
void Start() {
Vector2 sprite_size = GetComponent<SpriteRenderer> ().sprite.rect.size;
Vector2 spriteScale = transform.localScale;
float sizeAndScaleY = sprite_size.y * spriteScale.y;
float obstacle_local_sprite_sizeY = (sizeAndScaleY / GetComponent<SpriteRenderer> ().sprite.pixelsPerUnit) * 0.5F;
obstacleDimensionY = obstacle_local_sprite_sizeY;
}
// Update is called once per frame
void Update () {
transform.position += Vector3.up * constantSpeed * Time.deltaTime;
if (Time.time > selfDestroyTime) {
Destroy (gameObject);
}
}
}
ObstacleSpawn:
using UnityEngine;
using System.Collections;
public class ObstacleSpawn : MonoBehaviour {
public PlayerScript pScript;
public ObstacleScript oScript;
public GameObject player;
public GameObject obstacle;
public float randomSpawnMin;
public float randomSpawnMax;
// Use this for initialization
void Start () {
InvokeRepeating ("Spawn", 2F, Random.Range (randomSpawnMin, randomSpawnMax));
}
// Update is called once per frame
void Update () {
}
void Spawn() {
if (pScript.isRight == true && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (-1, 1, 1);
Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, 4F, 0), Quaternion.identity);
} else if (pScript.isRight == false && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (1, 1, 1);
Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, 4F, 0), Quaternion.identity);
}
}
}
However, by using timestamps between obstacle spawn and triggering with the character, I got the result of 0.5 interval instead of 1. Because of this I followed to try making it 8F instead of 4F, which should result in my 1 second interval, but it surprisingly gave a 0.86 interval.
I'm very unaware of what I'm missing, but I feel as there might be a flaw in the way I've set up my deltaTime.
Kind regards.
EDIT - Added code:
using UnityEngine;
using System.Collections;
public class ObstacleSpawn : MonoBehaviour {
public PlayerScript pScript;
public ObstacleScript oScript;
public GameObject player;
public GameObject obstacle;
public float randomSpawnMin;
public float randomSpawnMax;
// Use this for initialization
void Start () {
InvokeRepeating ("Spawn", 2F, Random.Range (randomSpawnMin, randomSpawnMax));
}
// Update is called once per frame
void Update () {
var diff = (player.transform.position - obstacle.transform.position);
diff = diff.normalized;
Vector3 speed = new Vector3 (100 * Time.deltaTime, 100 * Time.deltaTime, 100 * Time.deltaTime);
diff.x *= speed.x;
diff.y *= speed.y;
diff.z *= speed.z;
obstacle.transform.position = obstacle.transform.position + diff;
}
void Spawn() {
if (pScript.isRight == true && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (-1, 1, 1);
Instantiate (obstacle, obstacle.transform.position, Quaternion.identity);
} else if (pScript.isRight == false && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (1, 1, 1);
Instantiate (obstacle, obstacle.transform.position, Quaternion.identity);
}
}
}
var diff = ( Player.transform.position - RedTriangle.transform.position );
diff = diff.normalized;
var speed = Vector3(1*Time.deltaTime,1*Time.deltaTime,1*Time.deltaTime); // <- speed
diff.x *= speed.x;
diff.y *= speed.y;
diff.z *= speed.z;
RedTriangle.transform.position = RedTriangle.transform.position + diff;
Something like this needs to go in Update of a script. ( it will move the triangle towards the player )