Playing and Stopping Unity Particle System - c#

So i am using unity's Wheel Collider, and i want the particles to play when the wheels slide.
void CheckParticles()
{
WheelHit[] wheelHits = new WheelHit[4];
colliders.FRWheel.GetGroundHit(out wheelHits[0]);
colliders.FLWheel.GetGroundHit(out wheelHits[1]);
colliders.RRWheel.GetGroundHit(out wheelHits[2]);
colliders.RLWheel.GetGroundHit(out wheelHits[3]);
float slipAllowance = 0.1f;
// Particles for the front right wheel.
if ((Mathf.Abs(wheelHits[0].sidewaysSlip) + Mathf.Abs(wheelHits[0].forwardSlip) > slipAllowance))
{
wheelParticles.FRWheel.Play();
}
else
{
wheelParticles.FRWheel.Stop();
}
// Particles for the front left wheel.
if ((Mathf.Abs(wheelHits[1].sidewaysSlip) + Mathf.Abs(wheelHits[1].forwardSlip) > slipAllowance))
{
wheelParticles.FLWheel.Play();
}
else
{
wheelParticles.FLWheel.Stop();
}
// Particles for the rear right wheel.
if (Mathf.Abs(wheelHits[2].sidewaysSlip) + Mathf.Abs(wheelHits[2].forwardSlip) > slipAllowance)
{
wheelParticles.RRWheel.Play();
}
else
{
wheelParticles.RRWheel.Stop();
}
// Particles for the rear left wheel.
if (Mathf.Abs(wheelHits[3].sidewaysSlip) + Mathf.Abs(wheelHits[3].forwardSlip) > slipAllowance)
{
wheelParticles.RLWheel.Play();
}
else
{
wheelParticles.RLWheel.Stop();
}
}
I placed a debug.log in the if statements and it is triggering, but the particles aren't playing for some reason.
void CheckParticles()
{
WheelHit[] wheelHits = new WheelHit[4];
colliders.FRWheel.GetGroundHit(out wheelHits[0]);
colliders.FLWheel.GetGroundHit(out wheelHits[1]);
colliders.RRWheel.GetGroundHit(out wheelHits[2]);
colliders.RLWheel.GetGroundHit(out wheelHits[3]);
float slipAllowance = 0.1f;
// Particles for the front right wheel.
if ((Mathf.Abs(wheelHits[0].sidewaysSlip) + Mathf.Abs(wheelHits[0].forwardSlip) > slipAllowance))
{
wheelParticles.FRWheel.Play();
Debug.Log("Trigger FR Wheel Particles");
}
else
{
wheelParticles.FRWheel.Stop();
}
// Particles for the front left wheel.
if ((Mathf.Abs(wheelHits[1].sidewaysSlip) + Mathf.Abs(wheelHits[1].forwardSlip) > slipAllowance))
{
wheelParticles.FLWheel.Play();
Debug.Log("Trigger FL Wheel Particles");
}
else
{
wheelParticles.FLWheel.Stop();
}
// Particles for the rear right wheel.
if ((Mathf.Abs(wheelHits[2].sidewaysSlip) + Mathf.Abs(wheelHits[2].forwardSlip) > slipAllowance))
{
wheelParticles.RRWheel.Play();
Debug.Log("Trigger RR Wheel Particles");
}
else
{
wheelParticles.RRWheel.Stop();
}
// Particles for the rear left wheel.
if ((Mathf.Abs(wheelHits[3].sidewaysSlip) + Mathf.Abs(wheelHits[3].forwardSlip) > slipAllowance))
{
wheelParticles.RLWheel.Play();
Debug.Log("Trigger RL Wheel Particles");
}
else
{
wheelParticles.RLWheel.Stop();
}
}
It outputs all the Debug.Log's but no particles are being emitted, can't figure out the problem sadly. Been at it for almost the whole day.

Related

How to increment/decrement only by one when Ray hits

So, the game is to find a difference. When ray hits a collider of hidden object, it is supposed to add a score only of one and reduce a private integer differences value by one. But when the ray hits an object collider it is constantly incrementing/decrementing while the ray is hitting the collider. How can i change that? It is in the following method:
void Update()
{
camRay = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
Debug.DrawRay(camRay.origin, camRay.direction, Color.red, 1);
if (Input.touchCount > 0)
{
if (Physics.Raycast(camRay, out result))
{
/*{
obj = result.collider.gameObject;
score = score + 1;
differences= differences - 1;
score1.text = " " + score;
predmet.Play();
}*/
if (result.collider.CompareTag("Slike") && !hitOnce)
{
score +=1;
differences-= 1;
score1.text = " " + score;
predmet.Play();
}
else
{
hitOnce = false;
}
if (differences == 0)
{
WinPanel.SetActive(true);
}
}
}
}
When you first hit the object, you could remove or disable it's collider component. This should prevent it from being hit by more Raycasts.
On first hit, something like:
result.collider.enabled = false;

Can anyone help me make a script that rotates towards a specific angle

I am working on a unity game and
I have a gameobject i need to constantly rotate towards a target angle
And it needs to take the shortest way there
I have tried to use lerp co-routines to add/subbtract it to the angle but when i use it to quickly it gets stuck in weird positions
Transform target;
float speed;
//The angle to constantly rotate torwards
float yRotation = 120f;
private int dick;
void Start()
{
}
void Update()
{
if (Input.GetKeyDown(KeyCode.D))
{
if (dick < 3)
{
dick += 1;
}
else
{
dick = 1;
}
}
else if (Input.GetKeyDown(KeyCode.A))
{
if (dick >0 )
{
dick -= 1;
}
else
{
dick = 3;
}
}
if (dick == 1)
{
yRotation = 0;
}
else if (dick == 2)
{
yRotation = 120;
}
else if (dick == 3)
{
yRotation = 240;
}
As you might see there is some parts from the old code
The reason i use this kind of gear system is so that it cant get stuck in weird positions but i am not sure how to constantly rotate it to that target angle
Two things you can try :
In the Update, every time calculate the direction between you and the target, then calcultate the Angle, and then use Quaternion.AngleAxis() or simply Quaternion.RotateTowards()
You can also simply use Transform.LookAt(yourTarger.transform)

Change texture on key down

Here it is my method to get keyboard state and change texture based on which key is pressed.
private void CheckKeyboardAndUpdateMovement()
{
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyUp(Keys.Left)) { ChangeTexture(1); }
if (keyboardState.IsKeyUp(Keys.Right)) { ChangeTexture(2); }
if (keyboardState.IsKeyDown(Keys.Left))
{
Movement -= Vector2.UnitX;
ChangeTexture(3);
}
if (keyboardState.IsKeyDown(Keys.Right))
{
Movement += Vector2.UnitX;
ChangeTexture(4);
}
if ((keyboardState.IsKeyDown(Keys.Space) || keyboardState.IsKeyDown(Keys.Up)) && IsOnFirmGround())
{
Movement = -Vector2.UnitY * JumpHeight;
}
}
It works if direction are pressed, but doesn't make its own job when nothing is pressed (just because both the IsKeyUp are true). Only the cases' order prevents the static texture to be shown while moving the sprite...
My question is, how can I make a clean solution of this problem? I already have an idea, but I don't like it at all...
If you want another solution, but is still similar to yours.
enum Direction { Left = 1, Right = 2}
Direction dir = Direction.Left; //or whatever
private void CheckKeyboardAndUpdateMovement()
{
KeyboardState keyboardState = Keyboard.GetState();
ChangeTexture((int)dir);
if (keyboardState.IsKeyDown(Keys.Left))
{
Movement -= Vector2.UnitX;
ChangeTexture(3);
dir = Direction.Left;
}
if (keyboardState.IsKeyDown(Keys.Right))
{
Movement += Vector2.UnitX;
ChangeTexture(4);
dir = Direction.Right;
}
if ((keyboardState.IsKeyDown(Keys.Space) || keyboardState.IsKeyDown(Keys.Up)) && IsOnFirmGround())
{
Movement = -Vector2.UnitY * JumpHeight;
}
}
You can do something similar with walking sprites.
The worst solution I thought on, it's to store the sprite direction when the last key has been pressed and make a check on the next update, but it will become a mess more the keys and textures I'll have to control...
// Having a "bool leftDirectionOnLastMovement;" (worst name ever seen)
private void CheckKeyboardAndUpdateMovement()
{
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyUp(Keys.Left) && leftDirectionOnLastMovement)
ChangeTexture(1);
if (keyboardState.IsKeyUp(Keys.Right) && !leftDirectionOnLastMovement)
ChangeTexture(2);
if (keyboardState.IsKeyDown(Keys.Left))
{
Movement -= Vector2.UnitX;
ChangeTexture(3);
leftDirectionOnLastMovement = true;
}
}
if (keyboardState.IsKeyDown(Keys.Right))
{
Movement += Vector2.UnitX;
ChangeTexture(4);
leftDirectionOnLastMovement = false;
}
}
if ((keyboardState.IsKeyDown(Keys.Space) || keyboardState.IsKeyDown(Keys.Up)) && IsOnFirmGround())
{
Movement = -Vector2.UnitY * JumpHeight;
}
}
I really hope someone will suggest me a better way to do this...

Get UI ELement on touch

I'm sure I've read that there is a way of getting co-ordinates on Touch with Xna. But it's not really UIE, it's texture Draw in shapes.
For the moment I make them move like that:
void update()
TouchPanelCapabilities touchCap = TouchPanel.GetCapabilities();
if (touchCap.IsConnected)
{
TouchCollection touches = TouchPanel.GetState();
if (touches.Count >= 1)
{
Vector2 PositionTouch = touches[0].Position;
Position.X = PositionTouch.X - (t_Sprite.Width / 2);
Position.Y = PositionTouch.Y - (t_Sprite.Height / 2);
}
}
it's the method of my DragableObject Class.
I have defferents DragableObject, and my problem is when I move one Element, all others move too. Anyone helps?
What i have finally done and "works" for the moment. But dunno if its the good way for implement collision later.
public void Update(GameTime gametime)
{
Currentposition = Station.Position;
TouchPanelCapabilities touchCap = TouchPanel.GetCapabilities();
if (touchCap.IsConnected)
{
TouchCollection touches = TouchPanel.GetState();
if (touches.Count >= 1)
{
Vector2 PositionTouch = touches[0].Position;
for (int i = 0; i < ListDragObj.Count(); i++)
{
if (ListDragObj[i].Shape.Contains((int)PositionTouch.X, (int)PositionTouch.Y))
{
ListDragObj[i].selected = true;
}
else
{
ListDragObj[i].selected = false;
}
ListDragObj[i].Update(PositionTouch);
}
}
}
}

XNA 3.1 Movement Collision Issue

So heres my problem. I have a box that I want my character to move around. But I want to be able to move around it while holding multiple move commands, for instance..
when moving right (towards the left of the obstacle) I want to be able to hold move right and up or down at the same time without the character sticking to the box. The funny part is, it works fine for the left and right side of the obstacle, yet it sticks when i try it on the top and bottom side of the obstacle.
Heres the Player Class (object im moving)
<!-- language: c# -->
public class Player
{
public Texture2D texture;
public Vector2 position;
public int speed;
public Vector2 offset;
public bool left, right, up, down;
public Rectangle collisionRect
{
get
{
return new Rectangle((int)position.X , (int)position.Y, texture.Width, texture.Height);
}
}
public Vector2 direction;
public Player(Texture2D texture, Vector2 position, int speed)
{
this.texture = texture;
this.position = position;
this.speed = speed;
offset.X = speed;
offset.Y = speed;
left = false;
right = false;
up = false;
down = false;
}
public virtual void Update(GameTime gameTime, Rectangle clientBounds)
{
direction = Vector2.Zero;
if (Keyboard.GetState().IsKeyDown(Keys.A))
{
direction.X -= 1;
left = true;
}
else
left = false;
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
direction.X += 1;
right = true;
}
else
right = false;
if (Keyboard.GetState().IsKeyDown(Keys.W))
{
direction.Y -= 1;
up = true;
}
else
up = false;
if (Keyboard.GetState().IsKeyDown(Keys.S))
{
direction.Y += 1;
down = true;
}
else
down = false;
position += (direction * speed);
}
public virtual void Draw(GameTime gameTime, SpriteBatch spritebatch)
{
spritebatch.Draw(texture, collisionRect, Color.White);
}
}
Heres the Update Method in my maingame
<!-- language: c# -->
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
player.Update(gameTime, Game.Window.ClientBounds);
if (player.right && HitWall(player))
{
player.position.X -= player.offset.X;
}
else if (player.left && HitWall(player))
{
player.position.X += player.offset.X;
}
if (player.down && HitWall(player))
{
player.position.Y -= player.offset.Y;
}
else if (player.up && HitWall(player))
{
player.position.Y += player.offset.Y;
}
base.Update(gameTime);
}
And the HitWall function
<!-- language: c# -->
public bool HitWall(Player player)
{
for (int i = player.collisionRect.Top; i < player.collisionRect.Bottom; i++)
for (int j = player.collisionRect.Left; j < player.collisionRect.Right; j++)
if (TextureData[i * gameMap.map.Width + j] != Color.White)
return true;
return false;
}
I'm not sure where offset is defined, but I'm assuming it's the movement you've just made that frame.
Your problem is that because you check left & right before up and down, if you're moving diagonally down onto the top edge of the box, then you'll register a hit in the Y direction — HitWall doesn't check which direction you're going, it just checks for a collision. Therefore, the collision in the Y axis stil counts on the line if (player.right && HitWall(player)) and stops your lateral movement.
Best bet is to apply your sideways movement, check for a hit, move back if there is one — then apply your downwards movement, check for a hit, and move back if there is one. Correcting the position like this should mean you slide along the sides as you want.

Categories