A new <Russian accent>great success</Russian accent> in my game. I managed to have animations to control and I have a system that knows and shows whether the player enters or leaves a location. It took me an evening and a morning, but now it works.
First I needed to get a grip on how animations work. I saw a couple of videos about making doors open and close, but they all had a little problem in that they focusses on the door itself and I wanted to have the pivot of the door control it open, so I didn't need to move the door, just rotate the pivot. That worked fine, but I got to have a lot of work in the animator component, because the door could not close after being opened, immediately slammed shut after opening or it kept repeating the animations (the health system luckily did not react to being smashed between the door). Now I found out how to fix that.
Second is a generic inside/outside trigger system that I'm certainly going to use a lot in the future. There's a box collider that the player needs to go through to get to a location (just past the door, on the side of a village etc.). It notices if the player passes it and if it's relevant to act on it. If theplayer is outside the building and passes the Outside-trigger, it does nothing, but if it gets inside and passes the inside trigger, a boolean value will change and understand that passing the outside trigger will mean something else.
Here it is in action:
Showing posts with label collisions. Show all posts
Showing posts with label collisions. Show all posts
Sunday, 24 February 2019
Sunday, 10 February 2019
A collision problem with monsters and walls
Alright, I knew the monster would come back to bite me and it's giving me problems. I had a factory script build me a small 10x10 level which looks like this:
The stick figure in the left bottom corner, that's me. There's a couple of walls, a door, a health box and two monsters. I already made a script allowing the stick figure to walk through the level using keys, avoiding the walls and the door.
Now I added a script (bottom of this post) to the Monster class that makes it walk in a random direction (up, down, left or right) until it hits a collider. Then it decides another random direction (never the one it was already going) and moves on. I have this script. Note that Monster inherits from Enemy. All Enemy does is make sure a variable level contains an animation from the factory class. That happens in the base Awake.
This code results in the two monsters moving which is correct. The monster in the middle-right of the screen will go up and down and the one at the top will start moving places until it gets stuck in a corner like this:
As you see in the code, I added a Debug.Log to find out what is happening and it appears that the monster not only collides with the wall to its left and top, but also the one to the top-left. I suspect that the monster had its direction until it hit one of those walls, backs off in the OnCollisionEnter2D function and decides to hit the other two walls.
My question is if there's a way to get this thing to work: when the moveDir is decided, can the script predict immediate collisions without triggering them? I have this thing in the DecideMoveDir-method where I make sure the randomNumber is never the same as previousNumber so that the monster does not re-bump into the wall and get stuck. Can I broaden this while loop (or other thing) to make sure the resulting moveDir does not cause problems?
Or, maybe I'm just thinking wrong, does this phenomenon have another cause? Is that fixable? All I want to have here is the monsters walking in a random direction and chancing course randomly when they hit a wall, a door or each other. When they hit the player, something else will have to happen, but that's gonna be ugly.
Here's the entire Monster class script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : Enemy
{
private Sprite[] currentAnimation;
private int currentFrame = 0;
private float frameRate = .2f;
private float timer;
private SpriteRenderer spriteRenderer;
public Sprite[] monsterIdleAnimation;
private Vector3 moveDir;
private float speed = 2f;
private float speedTimer;
private int previousNumber;
protected override void Awake()
{
base.Awake();
monsterIdleAnimation = level.monsterIdleAnimation;
HealthSystem healthSystem = new HealthSystem(50);
currentAnimation = monsterIdleAnimation;
spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
moveDir = DecideMoveDir();
}
void Update()
{
MoveMonster(moveDir);
DecideMonsterAnimation();
AnimateMonster();
}
private void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log(gameObject.name + " / " + collision.gameObject.name + " nr:" + previousNumber);
transform.position -= moveDir;
moveDir = DecideMoveDir();
}
private int RandomNumberGenerator(int a, int b)
{
int getal = Random.Range(a, b);
return getal;
}
private Vector3 DecideMoveDir()
{
Vector3 direction = new Vector3();
//nooit twee keer dezelfde richting bepalen.
int randomNumber = RandomNumberGenerator(1, 4);
while (randomNumber == previousNumber)
{
randomNumber = RandomNumberGenerator(1, 4);
}
previousNumber = randomNumber;
switch (randomNumber)
{
case 1:
direction = Vector3.up;
break;
case 2:
direction = Vector3.down;
break;
case 3:
direction = Vector3.left;
break;
case 4:
direction = Vector3.right;
break;
default:
direction = Vector3.zero;
break;
}
direction *= speed * Time.deltaTime;
return direction;
}
public void MoveMonster(Vector3 direction)
{
transform.position += moveDir;
}
private void DecideMonsterAnimation()
{
//does nothing yet.
}
private void AnimateMonster()
{
timer += Time.deltaTime;
if (timer >= frameRate)
{
timer -= frameRate;
currentFrame = (currentFrame + 1) % currentAnimation.Length;
spriteRenderer.sprite = currentAnimation[currentFrame];
}
}
}
Subscribe to:
Posts (Atom)

