コード置き場「2DSTG #11 – #20」

コード置き場(2DSTG #11-#20)
スポンサーリンク

【2DSTG制作】の動画内で表示されるコード:#11 – #20

サムネイルをクリックすると、YouTubeの動画ページに移動します。

#12:スクリプトからLive2Dモデルの色を操作

サムネイル#12

Live2Dモデルの色を操作
using Live2D.Cubism.Rendering;


CubismRenderController renderController;

void Start()
{
    renderController = GetComponent<CubismRenderController>();
}

private IEnumerator HitColor()
{
    renderController.OverwriteFlagForModelScreenColors = true;

    yield return null;

    // スクリーンで白色を合成
    var screenColor = new Color(0.3f, 0.3f, 0.3f, 1.0f);

    // 全てのパーツに指定した色を適用する
    for (int i = 0; i < renderController.Renderers.Length; i++)
    {
        renderController.Renderers[i].ScreenColor = screenColor;
    }

    yield return new WaitForSeconds(0.03f);

    // 元の色に戻す
    renderController.OverwriteFlagForModelScreenColors = false;
}

#14:Animatorでポストプロセスを操作

サムネイル#14

Animator
Animator animator;

void Start()
{
    animator = GetComponent<Animator>();
}

--------------------------------------
  // 任意のタイミングで
  // モノクロのエフェクトを適用
  animator.SetTrigger("Monochrome");

  // 任意のタイミングで
  // モノクロのエフェクトを解除
  animator.SetTrigger("Color");

#15:レーザーの実装

サムネイル#15

Laser
// オブジェクト生成から削除するまでの時間
[SerializeField] float lifeTime = 1.0f;

// 弾の攻撃力
public int power = 1;

// レーザーか否か
public bool laser;

Renderer targetRenderer;

void Start()
{
    // lifeTime秒後に削除
    Destroy(gameObject, lifeTime);
    targetRenderer = GetComponent<Renderer>();
}

void Update()
{
    // 画面に表示されなくなったら
    if (!targetRenderer.isVisible) {
        if (laser == false) {
            // レーザー以外は削除
            Destroy(gameObject);
        } else {
            // レーザーは攻撃力ゼロ
            power = 0;
        }
    }
}

#16:反射レーザー

サムネイル#16

ReflectLaser
Vector2 lastVelocity = Vector2.zero;

Rigidbody2D rb2d;

void Start()
{
    rb2d = GetComponent<Rigidbody2D>();
}

void FixedUpdate()
{
    // 次の速度の計算用にVelocityの値を保持しておく
    lastVelocity = rb2d.velocity;
}

void OnCollisionEnter2D(Collision2D collision) {
    // 反射する地形に接触したら
    if (collision.gameObject.tag == "Terrain") {
        // 接触した地形に垂直な単位ベクトル(法線ベクトル)を取得
        Vector2 normalVector = collision.contacts[0].normal;
        // 反射ベクトルを計算
        Vector2 reflectVector = Vector2.Reflect(lastVelocity, normalVector);
        // 速度を更新
        rb2d.velocity = reflectVector;
    }
}

#17:追尾レーザー

サムネイル#17

HomingLaser
Vector3 velocity;

// 追尾レーザーの初期位置
Vector3 position;

Vector3 acceleration;

// ターゲットが存在しない時の目標位置
Vector3 randomPos;

Transform target;

// 追尾レーザーの初期位置に最も近いオブジェクト
GameObject searchNearObj;

// 着弾までの時間
[SerializeField] float period;

void Start()
{
    position = transform.position;
    searchNearObj = FindClosestEnemy();
    // ターゲットが存在すれば位置を取得
    if (searchNearObj != null) {
        target = searchNearObj.transform;
    }
    randomPos = new Vector3(4.0f, Random.Range(-1.5f, 1.5f), 0);
    // プレイヤーの斜め後ろにレーザーを発射
    velocity = new Vector3(Random.Range(-5.0f, -2.5f), Random.Range(-6.0f, 6.0f), 0);
}

void Update()
{
    acceleration = Vector3.zero;
    if (searchNearObj != null) {
        Vector3 diff = target.position - position;
        acceleration += (diff - velocity * period) * 2f / (period * period);
    } else {
        // ターゲットが存在しない場合は予備の目標地点に移動
        Vector3 diff = randomPos - position;
        acceleration += (diff - velocity * period) * 2f / (period * period);
    }

    period -= Time.deltaTime;
    if (period < 0f) {
        return;
    }

    velocity += acceleration * Time.deltaTime;
    position += velocity * Time.deltaTime;
    transform.position = position;
}

public GameObject FindClosestEnemy()
{
    // EnemyのTagを持つゲームオブジェクトの配列
    GameObject[] gos;
    gos = GameObject.FindGameObjectsWithTag("Enemy");
    // 最も近い位置に存在するEnemy
    GameObject closest = null;
    float distance = Mathf.Infinity;
    Vector3 position = transform.position;
    foreach (GameObject go in gos)
    {
        Vector3 diff = go.transform.position - position;
        float curDistance = diff.sqrMagnitude;
        if (curDistance < distance)
        {
            closest = go;
            distance = curDistance;
        }
    }
    // 最も近かったEnemyを返す
    return closest;
}

#18:追尾レーザー(同時に複数発射)・ヒットエフェクト

サムネイル#18

画面内の敵ユニットをランダムに取得
public GameObject[] FindEnemy()
{
    // EnemyのTagを持つゲームオブジェクトの配列
    GameObject[] gos;
    gos = GameObject.FindGameObjectsWithTag("Enemy");
    // 画面内の敵ユニットを格納する配列
    enemyList = new GameObject[6];
    int i = 0;
    foreach (GameObject go in gos)
    {
        // 画面外の敵ユニットは除外
        if (go.transform.position.x >= 4 || go.transform.position.x <= -4)
        {
            continue;
        }
        enemyList[i] = go;
        i++;
        if (i >= 6)
        {
            i = 0;
        }
    }
    return enemyList;
}
ヒットエフェクト
[SerializeField] GameObject hitEffect;

// ヒットエフェクトの生成
public void HitEffect()
{
    Instantiate(hitEffect, transform.position, transform.rotation);
}

void OnTriggerEnter2D(Collider2D collision)
{
    // 敵ユニットに当たったら
    if (collision.gameObject.tag == "Enemy")
    {
        // SEを再生
        SoundManager.instance.PlaySE();
        // ヒットエフェクトを生成
        HitEffect();
    }
}

#19:自機狙いの追尾レーザー

サムネイル#19

HomingLaser_Enemy
// 加速度の上限
[SerializeField] float limit;

void Update()
{
    var acceleration = Vector3.zero;
    var diff = target.position - position;
    acceleration += (diff - velocity * period) * 2f / (period * period);

    // 加速度の上限値を設定する
    if (acceleration.magnitude > limit)
    {
        acceleration = acceleration.normalized * limit;
    }

    period -= Time.deltaTime;

    velocity += acceleration * Time.deltaTime;
    position += velocity * Time.deltaTime;
    transform.position = position;
}

#20:ヒットストップの実装

サムネイル#20

画面の停止+カメラの揺れ
using DG.Tweening;


void Start()
{
    // 初期位置を取得
    initialPos = transform.position;
}

public void SampleB()
{
    // 画面の停止
    Time.timeScale = 0;
    // 対象を揺らす
    transform.DOShakePosition(0.4f, 0.3f, 30, 90)
        // timeScaleに影響されなくなる
        .SetUpdate(true)
        .OnComplete(() =>
        {
            // アニメーションが終了したら時間を元に戻す
            Time.timeScale = 1;
            // カメラの位置も戻す
            transform.position = initialPos;
        });
}

public void SampleC()
{
    Time.timeScale = 0;
    // 画面を強めに揺らす
    transform.DOShakePosition(1.0f, 0.8f, 30, 1)
        .SetUpdate(true)
        .OnComplete(() =>
        {
            transform.position = initialPos;
            // 画面をスローにする関数
            SlowMotion();
        });
}

void SlowMotion()
{
    Time.timeScale = 0.2f;
    // 3秒後にゲームオーバーの処理を実行
    DOVirtual.DelayedCall(3.0f, () => GameOver())
        .OnComplete(() =>
        {
            Time.timeScale = 1.0f;
        });
}
タイトルとURLをコピーしました