LoginSignup
2
1

More than 3 years have passed since last update.

[Unity] Project Tinyでのミニゲーム作成 - 当たり判定・アニメーション

Last updated at Posted at 2019-09-29

はじめに

Project Tinyでミニゲームを作成時に使用した機能やトラブルを説明していきます。
今回はゲーム中の当たり判定・アニメーションの実装についてです。
リポジトリはこちら

当たり判定

使用するコンポーネントはRectHitBox2Dです。

マニュアル
https://docs.unity3d.com/Packages/com.unity.tiny@0.16/manual/module-hitbox2d.html

判定方法

Sprite2DRnederer,RectHitBox2Dが設定されているEntity同士が接触すると
HitBoxOverlapコンポーネントが追加され、非接触の状態になると削除されます。
このHitBoxOverlapコンポーネントの存在の有無で当たり判定を行います。
今回のゲームではキャラクターが障害物に接触したら即ゲームオーバーなので、
HitBoxOverlapが存在したらゲームオーバーフラグを立てる処理を行っています。

GameMain.cs
Entities.ForEach((Entity entity, ref Character character, ref RectHitBox2D rectHitBox2d) => {
    if (EntityManager.HasComponent<HitBoxOverlap>(entity)) {
        isGameOver = true;
    }
});

不便な点

Colliderであれば設定したサイズをSceneビューで見ることが出来ますが、
RectHitBox2Dではそういうプレビュー的なものが存在しないためサイズ調整がなかなか難しいです。
なので、このランゲームではけっこういい加減な判定になっています。

アニメーション

Sprite2DSequenceとSprite2DSequencePlayerの2つのコンポーネントを使用します。

リファレンス
Sprite2DSequence
Sprite2DSequencePlayer

設定手順

  1. 適当なEntityにSprite2DSequenceをAdd Componentする
  2. アニメーションに使用するスプライトを各フレームに設定するSprite2DSequence.JPG

  3. Sprite2DRendererが設定されているEntityにSprite2DSequencePlayerをAdd Componentする

  4. Sprite2DSequencePlayerのsequenceにSprite2DSequenceのEnitityを設定するSprite2DSequencePlayer.JPG

Sprite2DSequencePlayerのフィールドの説明

sequence
Sprite2DSequenceが設定されているEntity

speed
再生スピード
1が通常スピード
1未満でスロー再生、1以上で倍速再生

time
現在の時間
値を設定することで途中からの再生を行うことができる

paused
一時停止

ループタイプ

Name Description
ClampFoever 再生後最終フレームを維持する
Loop 通常ループ
Once 一度だけ再生
PingPong いったり来たりをする再生を繰り返す
PingPongOnce PingPongを一度だけ行う

アニメーションの切り替え

Animationsコンポーネントを作成しその中に各アニメーションのSprite2DSequenceのEntityを設定できるようにしてあります。

Animations.cs
public struct Animations : IComponentData {
    public Entity SequenceIdleEntity;
    public Entity SequenceRunEntity;
    public Entity SequenceJumpEntity;
    public Entity SequenceDeathEntity;
}

あとはCharacterAnimationSystemで入力や状態を見て、Sprite2DSequencePlayerのsequenceのEntityを変更することでアニメーション切り替えを行っています。

CharacterAnimationSystem.cs
public class CharacterAnimationSystem : ComponentSystem {
    protected override void OnUpdate() {
        Entities.ForEach((ref Animations anims) => {
            var sequenceIdleEntity = anims.SequenceIdleEntity;
            var sequenceRunEntity = anims.SequenceRunEntity;
            var sequenceJumpEntity = anims.SequenceJumpEntity;
            var sequenceDeathEntity = anims.SequenceDeathEntity;
            var isGameOver = false;
            var isPlaying = false;
            var begun = false;
            var retry = false;

            Entities.ForEach((ref GameState game) => {
                isGameOver = (!game.GameOverPrev && game.GameOver);
                isPlaying = game.Playing;
                begun = game.Begun;
                retry = game.Retry;
            });

            Entities.ForEach((ref Character character, ref Sprite2DSequencePlayer sequencePlayer) => {
                if (true) {
                    if (isGameOver) {
                        // ゲームオーバー
                        sequencePlayer.time = 0.0f;
                        sequencePlayer.loop = LoopMode.ClampForever;
                        sequencePlayer.sequence = sequenceDeathEntity;
                    }
                    else if (begun) {
                        // ジャンプ
                        sequencePlayer.time = 0.0f;
                        sequencePlayer.loop = LoopMode.ClampForever;
                        sequencePlayer.sequence = sequenceJumpEntity;
                    }
                    else if (retry) {
                        // 走り
                        sequencePlayer.time = 0.0f;
                        sequencePlayer.loop = LoopMode.Loop;
                        sequencePlayer.sequence = sequenceRunEntity;
                    }
                    else {
                        if (!character.jumpingPrev && character.jumping) {
                            // ジャンプ
                            sequencePlayer.time = 0.0f;
                            sequencePlayer.loop = LoopMode.ClampForever;
                            sequencePlayer.sequence = sequenceJumpEntity;
                        }
                        else if (character.jumpingPrev && !character.jumping) {
                            // 着地
                            sequencePlayer.time = 0.0f;
                            sequencePlayer.loop = LoopMode.Loop;
                            sequencePlayer.sequence = sequenceRunEntity;
                        }
                    }
                }
            });
        });
    }
}
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1