MovingPlatform - move position1 to position2 then wait for 3 sec - c#

I have one PlatformManager (Script Attached)
One is Position-1
One is Position-2
One is MovingPlatform
I want.
MovingPlatform move Position-1 to Position-2 then wait for 5 Sec
then MovingPlatform move Position-2 to Position-1 then wait for 5 Sec
Here is code for PlatformManager & its working fine without Wait
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingPlatform : MonoBehaviour
{
public Transform movingPlatform;
public Transform position1;
public Transform position2;
public Vector3 newPosition;
public string currentState;
public float smooth;
public float resetTime;
private void Start()
{
ChangeTarget();
}
private void FixedUpdate()
{
movingPlatform.position = Vector3.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime);
}
void ChangeTarget()
{
if (currentState == "Moving To Position 1")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
}
else if (currentState == "Moving To Position 2")
{
currentState = "Moving To Position 1";
newPosition = position1.position;
}
else if (currentState == "")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
}
Invoke("ChangeTarget", resetTime);
}
}
I have tried this code but MovingPlatform didnt Wait
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestMovingPlatform : MonoBehaviour
{
public Transform movingPlatform;
public Transform position1;
public Transform position2;
public Vector3 newPosition;
public string currentState;
public float smooth;
public float resetTime;
IEnumerator Start()
{
while (true)
{
yield return StartCoroutine(ChangeTarget());
yield return new WaitForSeconds(3.0f);
}
}
private void FixedUpdate()
{
movingPlatform.position = Vector3.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime);
}
IEnumerator ChangeTarget()
{
if (currentState == "Moving To Position 1")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
}
else if (currentState == "Moving To Position 2")
{
currentState = "Moving To Position 1";
newPosition = position1.position;
}
else if (currentState == "")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
}
Invoke("ChangeTarget", resetTime);
yield return null;
}
}
Also i tried This but not success
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestMovingPlatform : MonoBehaviour
{
public Transform movingPlatform;
public Transform position1;
public Transform position2;
public Transform position3;
public Vector3 newPosition;
public string currentState;
public float smooth;
public float resetTime;
IEnumerator Start()
{
while (true)
{
yield return StartCoroutine(ChangeTarget());
}
}
private void FixedUpdate()
{
movingPlatform.position = Vector3.Lerp(movingPlatform.position, newPosition, smooth * Time.deltaTime);
}
IEnumerator ChangeTarget()
{
if (currentState == "Moving To Position 1")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
yield return new WaitForSeconds(3);
}
else if (currentState == "Moving To Position 2")
{
currentState = "Moving To Position 1";
newPosition = position1.position;
yield return new WaitForSeconds(3);
}
else if (currentState == "")
{
currentState = "Moving To Position 2";
newPosition = position2.position;
yield return new WaitForSeconds(3);
}
Invoke("ChangeTarget", resetTime);
yield return null;
}
}
Here i attached Screenshot of Hirerchy & Inspector
Also i tried other different MovingPlatform Scripts but MovingPlatform's movement is jerky when player ride on it.
Only this script. MovingPlatform's movement is smooth when Player ride on it.
Anyone idea how to solve this?

Here is a little script without states, just a small coroutine to achieve what you want :
// Drag & Drop the platform gameobject
public Transform movingPlatform;
// Drag & Drop all the GameObjects (empty) the platform must go to
public Transform[] positions;
private void Awake()
{
StartCoroutine( Run() );
}
private IEnumerator Run( float duration = 5f, float waitTime = 3f )
{
int index = 0;
float time = 0;
WaitForSeconds wait = new WaitForSeconds( waitTime );
while( true )
{
Vector3 startPosition = positions[index].position;
Vector3 endPosition = positions[ (index + 1) % positions.Length].position;
for ( time = 0 ; time < duration ; time += Time.deltaTime )
{
movingPlatform.position = Vector3.Lerp( startPosition, endPosition, Mathf.SmoothStep( 0, 1, time ) );
yield return null;
}
movingPlatform.position = endPosition;
index = ( index + 1 ) % positions.Length;
yield return wait;
}
}

First of all create some enumeration for your platform/paddle state
enum PaddleState
{
Retargetting,
Moving,
Stationary
}
Now add some fields to your behaviour :
PaddleState paddleState = PaddleState.Stationary;
Vector3[] targets;
int currentTargetIdx = 0;
float stationaryFor = 0.0f;
Change your Update() method to only do certain logic when paddle is in the correct state :
void Update()
{
if(CheckState())
{
ChangeState();
}
}
void CheckState()
{
switch(paddleState)
{
case PaddleState.Retargetting: // choose new target and reset stationary timer
{
stationaryFor = 0.0f;
if(targets.Length >= currentTargetIdx)
{
currentTargetIdx = 0;
}
paddletarget = targets[currentTargetIdx++]; // post increment
return true;
}
case PaddleState.Moving: // move paddle and check the distance to target, if distance is less than x then go to the stationary state
{
paddle.position = Vector3.Lerp(paddle.position, targets[currentTargetIdx], smooth * Time.deltaTime);
return Vector3.Distance(paddle.position, targets[currentTargetIdx]) < 0.5f; // arbitrary distance
}
case PaddleState.Stationary: // do not move for 3 seconds
{
stationaryFor += Time.deltaTime;
return stationaryFor >= 3.0f;
}
}
}
void ChangeState()
{
// go to the next state
paddleState = (int)paddleState + 1 > PaddleState.Stationary ? PaddleState.Retargeting : (PaddleState)((int)paddleState + 1);
}

Related

Is there a way to move object much faster on linerenderer line?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveOnCurvedLine : MonoBehaviour
{
public LineRenderer lineRenderer;
public GameObject objectToMove;
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
// Start is called before the first frame update
void Start()
{
pos = GetLinePointsInWorldSpace();
if (moveToFirstPositionOnStart == true)
{
objectToMove.transform.position = pos[index];
}
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true)
{
Move();
}
}
void Move()
{
objectToMove.transform.position = Vector3.MoveTowards(objectToMove.transform.position,
pos[index],
speed * Time.deltaTime);
if (objectToMove.transform.position == pos[index])
{
index += 1;
}
if (index == pos.Length)
index = 0;
}
}
Even if I'm setting the speed value to 1000 or even to 10000 the speed is faster but not so fast or not very fast.
There are 1157 position in the variable array positions. So it's a bit a problem to move fast no so many positions and in other cases there might be 5000 positions or more depending on the linerenderer line length.
but I saw in some youtube demos cars and objects moving fast very fast on curved lines or very long length lines.
Figure out how much distance to move in the current frame, then loop through points until you've traveled that distance:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveOnCurvedLine : MonoBehaviour
{
public LineRenderer lineRenderer;
public GameObject objectToMove;
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
// Start is called before the first frame update
void Start()
{
pos = GetLinePointsInWorldSpace();
if (moveToFirstPositionOnStart == true)
{
objectToMove.transform.position = pos[index];
}
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true)
{
Move();
}
}
void Move()
{
Vector3 newPos = objectToMove.transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
{
index = (index + 1) % pos.Length;
}
else
{
stillTraveling = false;
}
}
objectToMove.transform.position = newPos;
}
}

I'm creating a patrolling AI that aggros to the player and follows them in Unity 3D

I'm having trouble keeping this method running. It runs for 1 frame them shuts itself off. I am having trouble working out the logic to keep it running. Yes, the enemy does detect if the player is within a field of view, and it does stop when it collides with walls, it also stops detecting the player when they leave the fov.
I've tried changing around if statements, but it's overall very important that the code runs based on the player existing in the FOV collider. The problem is pretty specific, so I don't know what research to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(AudioSource))]
public class EnemyAI : MonoBehaviour
{
public float patrolSpeed, chaseSpeed, chaseWaitTime, patrolWaitTime, castRadius;
public Transform[] wayPoints, wayPOI;
public Transform player;
public Animation flinch, die;
public AudioClip grunt, callOut, death;
public LayerMask mask;
public PlayerCheck check;
private float chaseTimer, patrolTimer, wanderTimer;
private int destIndex, destInit, destStart, health;
private bool playerIn;
protected string aggro, resting, warned, sawPlayer;
protected bool patroling;
public bool aggress;
private NavMeshAgent agent;
private Transform playerLP;
private Vector3 startPos;
private Animator anim;
private AudioSource aud;
MeshCollider fieldOfView;
void Awake()
{
//patroling = true;
startPos = transform.position;
destInit = destIndex;
agent = GetComponent<NavMeshAgent>();
agent.autoRepath = true;
agent.autoBraking = true;
fieldOfView = transform.GetChild(0).GetComponent<MeshCollider>();
if (fieldOfView == null)
{
Debug.LogError("The first object MUST be FOV, otherwise the script will not work correctly. 1");
}
check = GameObject.FindObjectOfType<PlayerCheck>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
if (check == null)
{
check = GameObject.FindObjectOfType<PlayerCheck>();
}
playerIn = check.playerIn;
RaycastHit hit;
if (Physics.Linecast(transform.position, player.position, out hit, ~mask))
{
if (!playerIn)
{
Debug.DrawLine(transform.position, hit.point, Color.red);
}
else if (hit.collider.gameObject != null)
{
if (!hit.collider.CompareTag("Player"))
{
Debug.DrawLine(transform.position, hit.point, Color.blue);
return;
}
else
{
Debug.DrawLine(transform.position, hit.point, Color.green);
aggress = true;
}
}
}
if (aggress)
{
Aggro(sawPlayer);
}
if (patroling)
{
GoToNext();
}
}
void GoToNext()
{
patroling = true;
aggress = false;
if (wayPoints.Length == 0)
return;
if (playerIn)
return;
if (agent.remainingDistance < .7f)
{
agent.SetDestination(wayPoints[destIndex].position);
destIndex = (destIndex + 1) % wayPoints.Length;
}
}
void Aggro(string condition)
{
if (condition == sawPlayer)
{
Chase(player);
}
}
void Chase(Transform transform)
{
patroling = false;
if (playerIn)
{
agent.SetDestination(transform.position);
print("Chasing");
}
else
{
**Wander(sawPlayer, 15);**
print("Wander, please");
}
}
**void Wander(string condition, float time)**
{
patroling = false;
print(time);
wanderTimer += Time.deltaTime;
print("Wandering");
//this is where I'm having the most trouble, it will print wandering for 1 //frame then stop and go back to patroling
//once the player leaves the fov. I'm trying to figure out where the method //stops and why.
if (condition == sawPlayer)
{
if (wanderTimer >= time)
{
wanderTimer = 0;
if (!agent.pathPending && agent.remainingDistance < .5f)
{
GoToNext();
}
}
else
{
Vector3 vec;
vec = new Vector3(Random.Range(agent.destination.x - 10, agent.destination.x), Random.Range(agent.destination.y - 10, agent.destination.y), Random.Range(agent.destination.z - 10, agent.destination.z));
agent.destination = transform.InverseTransformDirection(vec);
if (agent.remainingDistance < .3f || wanderTimer > time)
{
GoToNext();
}
}
}
}
}

Unity 2D, control a simple shot

I have to control a shot of a ball with touch. All works fine but I need to start my trajectory when I touch the screen, but the trajectory start only when the ball is touched. Is because the script is attached to the ball?
All touch input except touches on the ball is ignored.
Here is the C# script , can someone help me?
using UnityEngine;
using System.Collections;
using System;
namespace Shorka.BallTrajectory
{
public enum PullState
{
Idle,
UserPulling,
ObjFlying
}
public class PullCtrl : MonoBehaviour
{
#region fields
//[SerializeField] private Transform throwTarget;
[SerializeField] private ThrownObject throwObj;
[SerializeField] private Transform dotHelper;
[SerializeField] private Transform pullingStartPoint;
[Space(5)]
[Tooltip("this linerenderer will draw the projected trajectory of the thrown object")]
[SerializeField]
private LineRenderer trajectoryLineRen;
[SerializeField]
private TrailMaker trail;
[Space(5)]
[SerializeField]
private float throwSpeed = 10F;
[Tooltip("Max Distance between 'PullingStartPoint' and pulling touch point")]
[SerializeField]
private float maxDistance = 1.5F;
[SerializeField]
private float coofDotHelper = 1.5F;
[Tooltip("Related to length of trajectory line")]
[SerializeField]
private int qtyOfsegments = 13;
[Tooltip("Step of changing trajectory dots offset in runtime")]
[SerializeField]
private float stepMatOffset = 0.01F;
[Tooltip("Z position of trajectory dots")]
[SerializeField]
private float dotPosZ = 0F;
private PullState pullState;
private Camera camMain;
//private Collider2D collThrowTarget;
private Rigidbody2D rgThrowTarget;
private Vector3 posPullingStart;
private Vector3 initPos;
private TrajectoryCtrl trajCtrl;
#endregion
public Vector3 PosDotHelper { get { return dotHelper.position; } }
public Vector3 PosThrowTarget { get { return throwObj.transform.position; } }
public int QtyOfsegments { get { return qtyOfsegments; } }
public float DotPosZ { get { return dotPosZ; } }
public Vector3 PosPullingStart { get { return posPullingStart; } }
public float StepMatOffset { get { return stepMatOffset; } }
void Awake()
{
trail.emit = false;
trajCtrl = new TrajectoryCtrl(this, trajectoryLineRen);
}
void Start()
{
camMain = Camera.main;
pullState = PullState.Idle;
posPullingStart = pullingStartPoint.position;
initPos = PosThrowTarget;
}
void Update()
{
SwitchStates();
}
private void SwitchStates()
{
switch (pullState)
{
case PullState.Idle:
if (Input.touchCount> 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
Debug.Log("Screen touched");
//get the point on screen user has tapped
Vector3 location = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
//if user has tapped onto the ball
if (throwObj.Collider == Physics2D.OverlapPoint(location))
pullState = PullState.UserPulling;
}
break;
case PullState.UserPulling:
dotHelper.gameObject.SetActive(true);
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
//get touch position
Vector3 touchPos = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
touchPos.z = 0;
//we will let the user pull the ball up to a maximum distance
if (Vector3.Distance(touchPos, posPullingStart) > maxDistance)
{
Vector3 maxPosition = (touchPos - posPullingStart).normalized * maxDistance + posPullingStart;
maxPosition.z = dotHelper.position.z;
dotHelper.position = maxPosition;
}
else
{
touchPos.z = dotHelper.position.z;
dotHelper.position = touchPos;
}
float distance = Vector3.Distance(posPullingStart, dotHelper.position);
trajCtrl.DisplayTrajectory(distance);
}
else if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Canceled || Input.GetTouch(0).phase == TouchPhase.Ended)
{
float distance = Vector3.Distance(posPullingStart, dotHelper.position);
trajectoryLineRen.enabled = false;
ThrowObj(distance);
}
break;
default:
break;
}
}
//private Vector2 velocityToRg = Vector2.zero;
private void ThrowObj(float distance)
{
Debug.Log("ThrowObj");
pullState = PullState.Idle;
Vector3 velocity = posPullingStart - dotHelper.position;
//velocityToRg = CalcVelocity(velocity, distance);
throwObj.ThrowObj(CalcVelocity(velocity, distance));
//rgThrowTarget.velocity = velocityToRg;
//rgThrowTarget.isKinematic = false;
trail.enabled = true;
trail.emit = true;
dotHelper.gameObject.SetActive(false);
}
public void Restart(Vector3 posThrownObj)
{
trail.emit = false;
trail.Clear();
StartCoroutine(ClearTrail());
trajectoryLineRen.enabled = false;
dotHelper.gameObject.SetActive(false);
pullState = PullState.Idle;
throwObj.Reset(posThrownObj);
}
private readonly WaitForSeconds wtTimeBeforeClear = new WaitForSeconds(0.3F);
IEnumerator ClearTrail()
{
yield return wtTimeBeforeClear;
trail.Clear();
trail.enabled = false;
}
Vector3 velocity = Vector3.zero;
public Vector3 CalcVelocity(Vector3 diff, float distance)
{
velocity.x = diff.x * throwSpeed * distance * coofDotHelper;
velocity.y = diff.y * throwSpeed * distance * coofDotHelper;
return velocity;
}
}
}
Its quite easy. you need to add these two scripts to the gameobject (not the ball but the one which is used to shoot the ball something like a gun)
TouchEventTrigger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class TouchEventTrigger : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler {
public TouchEvent onClick;
public TouchEvent onDown;
public TouchEvent onUp;
public void OnPointerClick(PointerEventData e) {
onClick.Invoke(e);
}
public void OnPointerDown(PointerEventData e) {
onDown.Invoke(e);
}
public void OnPointerUp(PointerEventData e) {
onUp.Invoke(e);
}
}
[System.Serializable]
public class TouchEvent : UnityEvent<PointerEventData> {}
Shooter.cs
public void TryBeginAim(PointerEventData e) {
if(canShoot) {
initialTouchPos = e.position;
}
}
public void TryAim(PointerEventData e) {
if(canShoot) {
direction = initialTouchPos - e.position;
float mag = (initialTouchPos - e.position).magnitude;
float scale = Mathf.Clamp(mag/maxMagnitude, scaleThreshold, 1f);
angle = Mathf.Atan2(direction.y,direction.x) * Mathf.Rad2Deg + 90f;
aim.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
aim.transform.localScale = Vector3.one * scale;
aim.SetActive(e.position.y < initialTouchPos.y);
}
}
public void TryShoot(PointerEventData e) {
if(canShoot && aim.activeInHierarchy) {
canShoot = false;
StartCoroutine(ShootRoutine(balls));
}
aim.SetActive(false);
}
private IEnumerator ShootRoutine(int b) {
// write code to start shooting balls.
}
Then connect the touch events with the methods like this:
1. OnPointerClick => TryBeginAim
2. OnPointerDown => TryAim
3. OnPointerUp => TryShoot
That's All !!
I hope this helps to solve this issue. Enjoy!

How do I get an object to move and swap places with another object, on a mouse clic

I have a script so far that moves an object a small distance upon a mouse click, however I want to change it so that when I click this object, it swaps places with another obejct next to it, instead of just the small distance it is moving now. I am a little confused on how to do this, because I am new to unity.
using UnityEngine;
using System.Collections;
public class NewBehaviourScript: MonoBehaviour
{
public float movementSpeed = 10;
void Update(){
if ( Input.GetMouseButtonDown(0))
{
transform.Translate(Vector3.right * movementSpeed * Time.deltaTime);
}
}
}
Try this:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript: MonoBehaviour {
public GameObject objectA; //Needs to be initialized in the editor, or on Start
public GameObject objectB; //Needs to be initialized in the editor, or on Start
public float movementSpeed = 10;
private Vector3 posA = Vector3.zero; //Vector3.zero is for initialization
private Vector3 posB = Vector3.zero; //Vector3.zero is for initialization
void Update() {
if ( Input.GetMouseButtonDown(0)) {
posA = objectA.gameObject.transform.position;
posB = objectB.gameObject.transform.position;
objectA.gameObject.transform.position = posB;
objectB.gameObject.transform.position = posA;
}
}
}
This just saves each objects position into the posA and posB variables, then you move objectA to posB and objectB to posA.
-OR-
Now if objectB is always a different object (NOT constant) and you aren't sure how to find the nearest object, you could use a raycast. Add the following function to your code:
gamObject NearestObject () {
int dist;
int nearestIndex;
//Create an array to contain objects to be hit by the raycast
RaycastHit[] nearby;
//Hit all objects within 100 units with a raycast, change the 100 as needed
nearby = Physics.RaycastAll(objectA.transform.position, transform.forward, 100.0f);
//Check if there is at least one object
if(nearby.Length > 0) {
//If there is only one object and it's not objectA
if(!(nearby.Length == 1 && nearby[0].transform == objectA.transform)) {
dist = nearby[0].distance;
nearestIndex = 0;
for (int i = 1; i < nearby.Length; i++) {
if(nearby[i].transform != gameObject.transform && nearby[i].distance < dist)
dist = nearby[i].distance;
nearestIndex = i;
}
}
} else {
//There is only one object in the raycast and it is objectA
nearestIndex = -1;
}
} else {
//There are no objects nearby
nearestIndex = -1;
}
//nearestIndex will only be negative one if there are no objects near objectA, so return null
if (nearestIndex == -1) {
return null;
} else {
//return nearest object to update
return nearby[nearestIndex].gameObject;
}
}
Finally, change Update to:
void Update() {
if ( Input.GetMouseButtonDown(0)) {
objectB = NearestObject ();
if (objectB != null) {
posA = objectA.gameObject.transform.position;
posB = objectB.gameObject.transform.position;
objectA.gameObject.transform.position = posB;
objectB.gameObject.transform.position = posA;
}
}
}
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{
//making them public just to be able watch values change in game mode
public float movementSpeed = 10;
public GameObject g1;
public GameObject g2;
public Vector3 vec1;
public Vector3 vec2 = new Vector3(2F, 2F, 2F);
public bool swapBack = false;
void Start()
{
g1 = GameObject.Find("Cube");
g2 = GameObject.Find("Sphere");
vec1 = new Vector3(g1.gameObject.transform.position.x, g1.gameObject.transform.position.y, g1.gameObject.transform.position.z);
vec2 = new Vector3(g2.gameObject.transform.position.x, g2.gameObject.transform.position.y, g2.gameObject.transform.position.z);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
transform.Translate(Vector3.right * movementSpeed * Time.deltaTime);
swap(swapBack);
}
}
public void swap(bool back)
{
if (back)
{
g1.transform.position = vec1;
g2.transform.position = vec2;
swapBack = false;
}
else
{
g1.transform.position = vec2;
g2.transform.position = vec1;
swapBack = true;
}
}
}

Unity2D: How to make spawn object gradually go faster after the player collects 10 points?

so I was wondering if there was a way to make a spawned object gradually moves/go faster after the player (you the user) collects 10 points. And faster when the player collects another 10 points and so on and so on?
This is my movement script attach to my objects that get spawned in:
public class Movement : MonoBehaviour
{
public static int movespeed = 20;
public Vector3 userDirection = Vector3.right;
public void Update()
{
transform.Translate(userDirection * movespeed * Time.deltaTime);
}
}
This is my score script attach to my player
public int Score;
public Text ScoreText;
void Start ()
{
Score = 0;
SetScoreText ();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (false);
Score = Score + 1;
SetScoreText ();
}
}
void SetScoreText ()
{
ScoreText.text = "Score: " + Score.ToString ();
}
And this is my generateEnemy script:
public GameOverManager gameOverManager = null;
[HideInInspector]
public float minBlobSpawnTime = 2;
[HideInInspector]
public float maxBlobSpawnTime = 5;
[HideInInspector]
public bool generateBlobs = true;
[HideInInspector]
public GameObject blobPrefab = null;
[HideInInspector]
public GameObject blobRoot = null;
[HideInInspector]
public float minimumYPosition = -0.425f;
[HideInInspector]
public float maximumYPosition = 0.35f;
[HideInInspector]
public float minDaggerSpawnTime = 2;
[HideInInspector]
public float maxDaggerSpawnTime = 5;
[HideInInspector]
public bool generateDaggers = true;
[HideInInspector]
public GameObject daggerPrefab = null;
[HideInInspector]
public GameObject daggerRoot;
[HideInInspector]
public float minimumXPosition = -11.5f;
[HideInInspector]
public float maximumXPosition = 11.5f;
public Camera camera = null;
// Use this for initialization
void Start ()
{
generateBlobs = ((generateBlobs) && (blobPrefab != null) && (blobRoot != null));
generateDaggers = ((generateDaggers) && (daggerPrefab != null) && (daggerRoot != null));
if (camera == null)
{
Debug.LogError("GenerateEnemy: camera is not set in the inspector. Please set and try again.");
camera = Camera.main;
}
if (gameOverManager == null)
{
Debug.LogError("GenerateEnemy: gameOverManager not set in the inspector. Please set and try again.");
}
if (generateBlobs)
{
StartCoroutine(GenerateRandomEnemy(true, blobPrefab, blobRoot, minBlobSpawnTime, maxBlobSpawnTime));
}
if (generateDaggers)
{
StartCoroutine(GenerateRandomEnemy(false, daggerPrefab, daggerRoot, minDaggerSpawnTime, maxDaggerSpawnTime));
}
}
// Update is called once per frame
void Update ()
{
DestroyOffScreenEnemies();
}
// Spawn an enemy
IEnumerator GenerateRandomEnemy(bool generateOnYAxis, GameObject prefab, GameObject root, float minSpawnTime, float maxSpawnTime)
{
if ((prefab != null) && (gameOverManager != null))
{
if (!gameOverManager.GameIsPaused())
{
GameObject newEnemy = (GameObject) Instantiate(prefab);
newEnemy.transform.SetParent(root.transform, true);
// set this in the prefab instead
// newEnemy.transform.position = new Vector3(newEnemy.transform.parent.position.x, 0.5f, newEnemy.transform.parent.position.z);
// or if you want the y position to be random you need to do something like this
if (generateOnYAxis)
{
newEnemy.transform.position = new Vector3(newEnemy.transform.parent.position.x, Random.Range(minimumYPosition, maximumYPosition), newEnemy.transform.parent.position.z);
}
else
{
newEnemy.transform.position = new Vector3(Random.Range(minimumXPosition, maximumXPosition), newEnemy.transform.parent.position.y, newEnemy.transform.parent.position.z);
}
}
}
yield return new WaitForSeconds(Random.Range(minSpawnTime, maxSpawnTime));
StartCoroutine(GenerateRandomEnemy(generateOnYAxis, prefab, root, minSpawnTime, maxSpawnTime));
}
public void DestroyOffScreenEnemies()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("enemy");
if ((enemies.Length > 0) && (camera != null))
{
for (int i = (enemies.Length - 1); i >= 0; i--)
{
// just a precaution
if ((enemies[i] != null) && ((camera.WorldToViewportPoint(enemies[i].transform.position).x > 1.03f) ||
(enemies[i].transform.position.y < -6f)))
{
Destroy(enemies[i]);
}
}
}
}
}
(This script has an generateEnemyCustomEditor script that references it, to show in the inspector)
Thank you :)
First of all, remove the static keyword from public static int movespeed = 20; and use GameObject.Find("ObjectMovementIsAttachedTo").GetComponent<Movement>(); to get the script instance if you want to modify movespeed variable from another script.
And faster when the player collects another 10 points and so on and so
on?
The solution is straight on. Use
if (Score % 10 == 0){
//Increement by number (4) movespeed from Movement script
movement.movespeed += 4;
}
to check if the Score is increased by 10 then increment movespeed by any value you want if that condition is true. It makes sense to put that in the OnTriggerEnter2D function after Score is incremented by 1.
Your new score script:
public class score : MonoBehaviour
{
public int Score;
public Text ScoreText;
private int moveSpeed;
void Start()
{
Score = 0;
SetScoreText();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Pick Up"))
{
other.gameObject.SetActive(false);
Score = Score + 1;
if (Score % 10 == 0)
{
//Increement by number (4) movespeed from Movement script
moveSpeed += 4;
}
SetScoreText();
}
}
public int getMoveSpeed()
{
return moveSpeed;
}
void SetScoreText()
{
ScoreText.text = "Score: " + Score.ToString();
}
}
Since your Movement script will be instantiated, when you instantiate it, you send its reference to the Player script.
public class Movement : MonoBehaviour
{
public int movespeed = 20;
public Vector3 userDirection = Vector3.right;
score mySpeed;
void Start()
{
//Send Movement instance to the score script
GameObject scoreGameObject = GameObject.Find("GameObjectScoreIsAttachedTo");
mySpeed = scoreGameObject.GetComponent<score>();
}
public void Update()
{
transform.Translate(userDirection * mySpeed.getMoveSpeed() * Time.deltaTime);
}
}

Categories