I am trying to make a platform that you can jump through and then when you press "Down" you can jump off the platform.
The problem is that when you press "Down" all the GameObjects on the platform fall down along with the player.
I managed to make a script using some tutorials that uses the "Platform Effector 2D" using this script.
private PlatformEffector2D effector;
public float waitTime;
void Start()
{
effector = GetComponent<PlatformEffector2D>();
}
void Update()
{
if(Input.GetKeyUp(KeyCode.S))
{
waitTime = 0.5f;
}
if(Input.GetKey(KeyCode.S))
{
if(waitTime <= 0)
{
effector.rotationalOffset = 180f;
waitTime = 0.5f;
}
else
{
waitTime -= Time.deltaTime;
}
}
if (Input.GetButtonDown("Jump"))
{
effector.rotationalOffset = 0;
}
}
Related
I am very new to c# and I've come across a problem with my enemy spawner. I am making an endless top-down shooter, and after 20 enemies have been spawned and then destroyed, the enemies stop appearing. My score counter continues to increase though, which leads me to believe they're somehow being destroyed.
Here is the enemy spawn controller:
void Update()
{
if (!spawningObject && GameController.EnemyCount < spawnSettings[0].maxObjects)
{
spawningObject = true;
float pick = Random.value * totalWeight;
int chosenIndex = 0;
float cumulativeWeight = enemySpawnables[0].weight;
while(pick > cumulativeWeight && chosenIndex < enemySpawnables.Count - 1)
{
chosenIndex++;
cumulativeWeight += enemySpawnables[chosenIndex].weight;
}
StartCoroutine(SpawnObject(enemySpawnables[chosenIndex].type, Random.Range(spawnSettings[0].minWait / GameController.DifficultyMultiplier, spawnSettings[0].maxWait / GameController.DifficultyMultiplier)));
Spawn();
}
}
private IEnumerator SpawnObject(string type, float time)
{
yield return new WaitForSeconds(time);
randomSpawnPoint = Random.Range(0, enemySpawners.Length);
randomEnemy = Random.Range(0, enemy.Length);
enemyPool.SpawnObject(enemySpawners[randomSpawnPoint].position, transform.rotation);
spawningObject = false;
GameController.EnemyCount++;
}
And here is the enemy controller (attached to enemy prefab):
public void Start()
{
myRB = GetComponent<Rigidbody>();
player = FindObjectOfType<PlayerController>();
}
private void OnEnable()
{
player = FindObjectOfType<PlayerController>();
}
void Update()
{
if (health <= 0)
{
Die();
}
}
void FixedUpdate()
{
transform.LookAt(player.transform.position);
myRB.velocity = (transform.forward * moveSpeed);
//Falling
if(myRB.velocity.y < 0)
{
myRB.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
}
}
public void Die()
{
print("Enemy" + this.gameObject.name + " has died!");
EnemySpawn.instance.enemyPool.ReturnObject(this.gameObject);
player.GetComponent<PlayerController>().points += pointsToGive;
ScoreController.scoreValue += 1;
}
The only thing that should affect enemy health is the bullet. Here is the part of the bullet controller that affects enemy health:
public void OnTriggerEnter(Collider other)
{
if(other.tag == "Enemy")
{
triggeringEnemy = other.gameObject;
triggeringEnemy.GetComponent<EnemyController>().health -= damage;
PlayerController.instance.bulletPool.ReturnObject(gameObject);
}
}
The issue always happens after 20 enemies have been spawned/destroyed and 20 points have been achieved. Before then, enemy movement is normal and everything seems to be working as it should. It could very well be something very simple that I'm missing, but I'd appreciate any help!
When you do engage logic mistake good way to find it is Visual Studio debugging.
Here is good official article about whole process - https://docs.unity3d.com/Manual/ManagedCodeDebugging.html.
I would place breakpoint right at start of Update method to see that EnemyCount increases over time and then you will understand that you forgot to do decrement it.
I am working on solo project that is horizontal 2D infinite runner. I have a problem in jumping mechanics where player can hold the jump button and jump as soon as he touches the ground. I want to force player to release the button to be able to jump again. I want to make same mechanics when he is floating(at the end of the jump when player starts falling down its y velocity is being reduced for few bits of second). I am following single responsibility principle so jumping and floating are 2 seperate scripts.
I have tried to implement a timer that will count while player is touching the ground and after some time the player would be able to jump again, but didn't manage to get asked result because you can hold the jump button all the time and after determined time spent on ground player would just jump again without releasing the button.
public class Jumping : MonoBehaviour
{
public bool isJumping;
public bool isGrounded;
public float speedUp;
public float verticalAxis;
public float timePassed;
public float jumpLimit;
private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
verticalAxis = Input.GetAxisRaw("Vertical");
if (verticalAxis > 0 && timePassed == 0)
{
isJumping = true;
}
}
private void FixedUpdate()
{
if (isJumping)
{
Jump();
}
}
private void OnCollisionStay2D(Collision2D collision)
{
if (collision.collider.tag == "Ground")
{
isGrounded = true;
timePassed = 0f;
}
}
private void Jump()
{
isGrounded = false;
//Modifying y component of players rigidbody(jumping)
Vector2 velocity = Vector2.up * speedUp * verticalAxis;
rb.velocity = velocity;
//Counting time when jumping
timePassed += Time.deltaTime;
if (timePassed >= jumpLimit)
{
isJumping = false;
}
}
}
P.S. I have tried to shrink the code in this question as stackoverflow suggests but I didn't know what to cut out because according to me everything is relevant and crucial to solving the problem. Thanks!
without knowing the rest of your code I would use an additional flag and obviously something for getting the cool down delay like
public float jumpCoolDownTime;
private float coolDownTimer;
private bool canJump;
void Update()
{
// if no can jump you can't jump again
if(!canJump)
{
verticalAxis = Input.GetAxisRaw("Vertical");
if (verticalAxis > 0)
{
canJump = false;
isJumping = true;
coolDownTimer = 0;
}
}
else
{
// run timer to enable jump again
if(isGrounded) coolDownTimer += Time.deltaTime;
if(coolDownTimer >= jumpCoolDownTime)
{
canJump = true;
}
}
}
You could however simplify the code a bit using Coroutines
public bool isJumping;
public float speedUp;
public float verticalAxis;
public float jumpLimit;
public float coolDownTime;
private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
}
void Update()
{
// do nothing is already jumping
if(isJumping) return;
verticalAxis = Input.GetAxisRaw("Vertical");
if (verticalAxis > 0)
{
// start jumping
StartCoroutine(Jump());
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.tag != "Ground") return;
isGrounded = true;
StartCoroutine(CoolDown());
}
private IEnumerator Jump()
{
isJumping = true;
isGrounded = false;
coolDownTimer = 0;
var timePassed = 0f;
while(timePassed < jumpLimit)
{
// wait for the FixedUpdate call
yield return new WaitForFixedUpdate();
Vector2 velocity = Vector2.up * speedUp * verticalAxis;
rb.velocity = velocity;
}
}
private IEnumerator CoolDown()
{
yield return new WaitForSeoncds(coolDownTime);
isJumping = false;
}
If you are using the axis to get the jump, you can see if the player have released the button by:
if (GetAxis("Vertical") == 0.0) { //Button up
// do stuff
}
if(GetAxis("Vertical") > 0)
{
//Button down, is jumping
}
In Unity axis aren't booleans, they are coefficients, if you play with a controller you can set different behaviors for different intensities.
i made a rain particle system in unity 2d and attached it as a child to main camera so it can move along with the camera towards north. but the rain effect is not perfect as some of the particles are wobbling upward. i have attached a script to the camera which is given below. is there any other way to resolve this issue.
public float translation ;
public float highspeed;//highest speed of the camera
public float incfactor;//increasing ,multiplying number
float timer=0f ;
public bool ismoving = false;
Rigidbody2D dia;
void Start()
{
dia = GetComponent<Rigidbody2D> ();
}
void Update()
{
if (Input.GetMouseButtonDown(0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if(hit.collider != null) {
if (hit.collider.tag =="dialogue") {
FindObjectOfType<audioManager> ().Play ("levelbeginclick");
Destroy (hit.collider.gameObject);
ismoving = true;
}
}
}
if (ismoving == true) {
Updatemove ();
}
}
public void Updatemove ()
{
timer += Time.deltaTime;
if (timer > 1f&& translation<highspeed) {
timer = 0; // reset timer
translation +=incfactor ;
}
transform.Translate (0, translation*Time.deltaTime, 0);
}
public void stopmoving()
{
ismoving = false;
}
}
So changing the Simulation Space to World as #ARutherford said should do the trick
I am a beginner in Unity and following Udemy tutorials for learning VR using Unity and making a game named Ninja Slash. Everything seems to be working fine in the Unity Editor Play mode but when I run my app in a real device, my player doesn't move at all. I can't figure out what is the problem here.
Here is my Player script.
public class Player : MonoBehaviour {
public GameObject sword;
public float speed = 4.5f;
public float walkingAmplitude = 0.25f;
public float walkingFrequency = 2.0f;
public float swordRange = 1.75f;
public float swordCooldown = 0.25f;
public bool isDead = false;
public bool hasCrossedFinishLine = false;
private float cooldownTimer;
private Vector3 swordTargetPosition;
// Use this for initialization
void Start () {
swordTargetPosition = sword.transform.localPosition;
}
// Update is called once per frame
void Update () {
if (isDead) {
return;
}
transform.position += Vector3.forward * speed * Time.deltaTime;
transform.position = new Vector3(
transform.position.x,
1.7f + Mathf.Cos(transform.position.z * walkingFrequency) * walkingAmplitude,
transform.position.z
);
cooldownTimer -= Time.deltaTime;
if (GvrViewer.Instance.Triggered ) {
RaycastHit hit;
if (cooldownTimer <= 0f && Physics.Raycast(transform.position, transform.forward, out hit)) {
cooldownTimer = swordCooldown;
if (hit.transform.GetComponent<Enemy> () != null && hit.transform.position.z - this.transform.position.z < swordRange) {
Destroy (hit.transform.gameObject);
swordTargetPosition = new Vector3 (-swordTargetPosition.x, swordTargetPosition.y, swordTargetPosition.z);
}
}
}
sword.transform.localPosition = Vector3.Lerp (sword.transform.localPosition, swordTargetPosition, Time.deltaTime * 15f);
}
void OnTriggerEnter (Collider collider) {
if (collider.GetComponent<Enemy> () != null) {
isDead = true;
} else if (collider.tag == "FinishLine") {
hasCrossedFinishLine = true;
}
}}
Here is the screenshot for hierarchy view.
I tried with different version gvr sdk unity package but I am getting same result everytime and I also tried running it different devices like htc,samsung etc.
I believe you can't change the transform of the main camera in VR mode. You have to make the maincamera as a child of another object (empty?!) and then move that object.
I'm trying to find a way to pause my game in Unity without using "Time.timeScale = 0;". The reason I want to change this is that I want to make the character play an animation while the game is paused. Is there a way to change this script so that the gravity and forward speed only "sets in" after the player have clicked space? Or is there a better way to solve the problem?
This is the script:
public class PlayerMove : MonoBehaviour {
Vector3 velocity = Vector3.zero;
public Vector3 gravity;
public Vector3 FlyVelocity;
public float maxSpeed = 5f;
public float forwardSpeed = 1f;
bool didFly = false;
bool dead = false;
float deathCooldown;
Animator animator;
// Use this for initialization
void Start () {
animator = GetComponentInChildren<Animator>();
}
// Do Graphic & Input updates here
void Update(){
if (dead) {
deathCooldown -= Time.deltaTime;
if (deathCooldown <= 0) {
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) ) {
Application.LoadLevel( Application.loadedLevel );
}
}
}
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) ) {
didFly = true;
animator.SetTrigger ("DoFly");
}
}
void OnCollisionEnter2D(Collision2D collision) {
animator.SetTrigger ("Death");
dead = true;
}
// Do physics engine updates here
void FixedUpdate () {
if (dead)
return;
velocity += gravity * Time.deltaTime;
velocity.x = forwardSpeed;
if(didFly == true) {
didFly = false;
velocity += FlyVelocity;
}
velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
transform.position += velocity * Time.deltaTime;
deathCooldown = 0.5f;
}
}
If you are using Mechanim you could update animation state from script using Animator.Update even while actual time scale is zero.
Not sure if the trick is possible with legacy animation.