I am making a jumping and idle animations in Unity 3d.
Here is the code:
using UnityEngine;
using System.Collections;
public class JumpingD : MonoBehaviour
{
public Animator anim;
public float JumpSpeed_;
private RigidBody _Character; //rigid body of the Character
public Vector3 JumpVector;
/*The thresh Hold level for the character to jump are
1: Stay Idle
25: Jump Up
*/
void Start ()
{
anim=GetComponent<Animator>();
anim.SetFloat("JumpSpeed", 1)
}
void Update ()
{
anim.SetFloat("JumpSpeed", 1)
if(Input.GetKeyDown(KeyCode.J))
{
_Character.AddForce(JumpVector*Time.deltaTime);
anim.SetFloat("JumpSpeed", 25)
}
}
}
The problem is the jump animation don't play even after J key is pressed.
Always the idle animation plays
I want the jump animation to play after I pressed J key and after that the character goes idle again.
On the first line of your update method, which gets called every frame, you set "JumpSpeed" to 1. It means that the next frame the player will stop pressing the J key, it will immediately drop to 1, so of course jump animation won't play "after" the player pressed J key.
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MakePipe : MonoBehaviour
{
public GameObject pipe;
float timer = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
timer += Time.deltaTime;
if (timer > 1)
{
Instantiate(pipe);
timer = 0;
}
}
}
I am trying to instantiate pipes using prefab, and with the code, a new set of pipes should spawn and move left from the original position where the first set of pipes spawned, but they are not visible.
They are generated as clones in the hierarchy, but when I double-click them to check the position, it points towards the first pipe position.
My guess is that new clones are generated and overlapped in the first pipe as they move together.
Please help
Thanks for your reply.
Sorry I didn't add a separate cs code 'move', I should have added gif..
The following code is to move the pipe left with certain speed. There is no problem there.
However from the 'MakePipe' code that I originally posted, I used instantiate to keep reproducing the pipe. Maybe I should add some lines to 'Start()' part to set original spawn location?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += Vector3.left * speed * Time.deltaTime;
// Debug.Log(transform.position);
}
}
I had to delete photos because error message tells me I should have more than 10 reps to edit :(
I don't have enough rep to comment, I'll attempt to give you a answer and update it for what you need.
The Object.Instantiate method has some parameters that you can use to get your pipes into place.
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation, Transform parent);
And without the overloads it will use the original prefab's parameters. So they will spawn in the same location. You have to calculate the next position and pass it in the Instantiate method (Vector3 position).
I misunderstood what you are trying to do at first. #Geeky Quentin
gave the right answer in the first comment.
[SerializeField] private GameObject pipe;
float timer = 0;
float offset = 1.5f;
void Start()
{
}
void Update()
{
timer += Time.deltaTime;
transform.position += new Vector3(-Time.deltaTime/offset, 0, 0);
if (timer > 1)
{
GameObject lastPipe = Instantiate(pipe);
lastPipe.transform.SetParent(transform);
timer = 0;
}
}
I still don't have enough rep to comment. Regarding your last changes. I tested your code out.
Are you parenting the instantiated pipe to the PipeMaker in another script? If not this is the effect it spawns but it does not move:
To make it work you need to parent the instantiated pipe and change it's position MakePipe.cs:
public GameObject pipe;
float timer = 0;
private GameObject _newPipe;
void Update()
{
timer += Time.deltaTime;
if (timer > 1)
{
//instatiate with parent on transform
_newPipe = Instantiate(pipe, transform);
//Set positiion to orginal prefab position
_newPipe.transform.position = pipe.transform.position;
timer = 0;
}
}
This is the effect:
My PipeSpawner has the Move and MakePipe scripts attached to it. And the prefab is in a hidden PipePrefab object that's unrelated to the rest of the system.
You could also set the position of the original spawn location in your Start() method as you said, it's up to you.
I'm trying to make a top-down shooter game in unity 2d. But the enemies are always clumping together. Does someone knows how to avoid it?
Here's my enemy code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float moveSpeed;
public float stoppingDistance;
public Transform player;
private Rigidbody2D rb;
public GameObject effect;
public int health = 3;
public static int enemyCounter;
public SpriteRenderer enemy;
public Color hurtColor;
void Start() {
rb = GetComponent<Rigidbody2D>();
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update() {
enemyCounter = EnemySpawner.enemyCounter;
Vector2 direction = transform.position - player.position;
if (Vector2.Distance(transform.position, player.position) > stoppingDistance) {
transform.position = Vector2.MoveTowards(transform.position, player.position,
moveSpeed * Time.deltaTime);
}
else if (Vector2.Distance(transform.position, player.position) > stoppingDistance) {
transform.position = this.transform.position;
}
}
IEnumerator Flash(){
enemy.color = hurtColor;
yield return new WaitForSeconds(0.01f);
enemy.color = Color.red;
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "Bullet") {
StartCoroutine(Flash());
health -= 1;
}
if (health <= 0) {
GameObject DestroyEnemy = Instantiate(effect, transform.position, Quaternion.identity);
Destroy(this.gameObject);
Destroy(DestroyEnemy, 2f);
}
}
}
The enemies is moving towards the player, but they clump together when I move the player. I really need help.
If the enemies are moving in straight line to the player they will always clump up. If you want to ensure a minimal distance between enemies you could consider using a second larger collider on another layer but this will might end up looking bad and could make some exploits possible if too big.
The other alternative would be to change the behaviour of the enemies. Making an enemy move depending on the position of the other enemies seems complicated therefore i would simply try to add some randomness to their behaviour. Here are some ideas you could try:
-(would be my first try) switch randomly between two behaviours, 1: move straight to the player (always if very close to player), 2: move in a random direction (sometimes when further away from the player)
-don't give all your enemies the same speed
-make them move towards the player + a small random angle away from the player if far away
-...
To sum it up you will need an improved behaviour and there isn't a single solution.
I have a punch animation with, let's assume, 5 frames;
the second frame is the punch collision itself. I wanna be able to duplicate this keyframe and move the following frames forward.
I wanna be able to do this when there is a collision. Making the animation slower doesn't work because it would delay the whole frames.
any tips
Maybe you could pause the animation, wait for a few frames, and then resume it. Animation can be paused by setting Animator.speed to 0. Something like this:
public class PunchAnimation : MonoBehaviour {
public Animator animator;
public float delay;
IEnumerator WaitAndResume(Animator animator, float delay) {
animator.speed = 0;
yield return new WaitForSeconds(delay);
animator.speed = 1;
}
void OnCollisionEnter(Collision c) {
StartCoroutine(WaitAndResume(animator, delay));
}
}
I'd like to animate my Score-GUI text counting up to a variable value but there are two things in my way:
1: How can I animate to a variable instead of a fixed value?
2: Why can't I add own properties (like int) to my script and animate them?
For #2 I created a property in my script. Yet the editor won't show it in the AddProperty-dialog (as shown below):
public int currentScore = 0;
public int score {
get { return currentScore; }
set { this.currentScore += value; }
}
EDIT: The animator is set up in the most basic way:
Since you only have 1 Animation. An Animator is irrelevant to the solution. This is tested and working. Now you need to make the Animation a Legacy type to get this working because we are not going to use the Animator.
Click the Animation on the Project -> look at the upper right section of the Inspector view, there is a little button there which will drop down a selection. "Debug" then Check the Legacy.
Set your Animation to whatever you want. I force the WrapMode in the script to be wrap mode once. So it will only play once.
Now in the Animation Component make sure you select the Animation that you want by default or it wont work. Cause we only use anim.Play(); Without parameters meaning, run the default animation that is set.
I created a Text UI and added an Animation that alpha is 0 from the start and at the end point making it 1. You have to do that on your own.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class MyScore : MonoBehaviour {
// Use this for initialization
public int currentScore = 0;
public GameObject Myscore; // Drag the GameObject that has the Animation for your score.
public Text myScoreText; //Drag in the Inspector the Text object to reference
public Animation anim;
public int score
{
get { return currentScore; }
set { this.currentScore += value; }
}
void Start()
{
anim = Myscore.GetComponent<Animation>(); // Reference the Animation Component.
anim.wrapMode = WrapMode.Once; // Legacy animation Set to play once
AddScore();
}
public void AddScore()
{
score += 10;
myScoreText.text = score.ToString();
anim.Play();
Debug.Log("Current Score is "+ score);
Invoke("AddScore", 2);
}
}
Good luck.
I have a 3dtext named Play, which when clicked will play the animation; the other one is named Back, which reverses the animation. Problem is after I Played and Backed it, the animation wont play anymore when i clicked Play.
The animation named redsubmenu is in legacy and clamp forever wrap mode.
public class PlayButtonScript : MonoBehaviour {
//public static PlayButtonScript pbs;
public GameObject redsubmenu;
void Update(){
#if UNITY_EDITOR
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Input.GetMouseButtonDown(0)&&Physics.Raycast(ray,out hit)){
if(hit.collider.name == "Play"){
redsubmenu.animation.Play();
}
}
#endif
}
}
public class BackButtonScript : MonoBehaviour {
// Update is called once per frame
void Update () {
#if UNITY_EDITOR
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Input.GetMouseButtonDown(0)&&Physics.Raycast(ray, out hit)){
if(hit.collider.name == "Back"){
transform.parent.animation["redsubmenu"].speed = -1;
transform.parent.animation.Play("redsubmenu");
}
}
#endif
}
}
It appears that you never reset the speed of the animation back to 1. When you click play the first time the speed is initially 1, so it works fine. However, when you back you set the speed to -1 and it is never set to any other value.
Try using:
if (hit.collider.name == "Play") {
transform.parent.animation["redsubmenu"].speed = 1;
redsubmenu.animation.Play();
}
in your play button script.
You might also be able to make use of Animation.Rewind.
http://docs.unity3d.com/ScriptReference/Animation.Rewind.html
Just to be more specific, i edited my playbuttonscript as shown below:
if(Input.GetMouseButtonDown(0)&&Physics.Raycast(ray,out hit)){
if(hit.collider.name == "Play"){
if(redsubmenu.animation["redsubmenu"].speed == -1){
redsubmenu.animation["redsubmenu"].speed = 1;
} else {
redsubmenu.animation.Play();
}
}
}
in my back button, i delete the transform.parent.animation.Play, no need for that.