Outline
職業訓練の終了課題で横スクロールシューティングの作成を担当しました。
今回は中ボスの作成をしました。
敵が画面上部で停滞⇒画面下部に移動⇒画面下部で停滞⇒画面上部に移動を繰り返すような動きにしました。
その際矩形波をフーリエ級数展開し第2項で打ち切ったものを用いました。
フーリエ級数
矩形波のフーリエ級数展開は下のようになる。この式のうちn=1,2について合計した。(ただし4/πは省略した)
PackageDownLoad(一部です)
Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EagleS2 : MonoBehaviour
{
GameObject player;
public GameObject bulletPref;
GameObject camera;
int loopCnt;
const int maxHp = 200;
int hp;
bool isAngry=false;
Vector2 initPos;
// Start is called before the first frame update
void Start()
{
initPos = transform.position;
hp=maxHp;
loopCnt = 0;
camera = GameObject.FindGameObjectWithTag("MainCamera");
if(camera!=null)
{
transform.SetParent(camera.transform);
}
player = GameObject.FindGameObjectWithTag("MyShip");
camera.GetComponent().nowCameraMove = false;
}
// Update is called once per frame
void Update()
{
if (hp <= 0)
{
camera.GetComponent().nowCameraMove = true;
Destroy(gameObject);
}
else if (hp < maxHp / 2)
{
isAngry = true;
}
}
private void FixedUpdate()
{
Vector2 v;
GameObject bullet;
if (bulletPref!=null && player!=null && camera!=null && loopCnt%10==0)
{
v = (player.transform.position - this.transform.position).normalized * 5;
bullet = Instantiate(bulletPref, transform.position, Quaternion.identity);
bullet.transform.SetParent(camera.transform);
bullet.GetComponent().velocity = v;
if(isAngry)
{
int startDeg=loopCnt*3;
for(int i=startDeg;i<(startDeg+360);i+=20) {
float rad=i*Mathf.Deg2Rad;
v=new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
bullet = Instantiate(bulletPref, transform.position, Quaternion.identity);
bullet.transform.SetParent(camera.transform);
bullet.GetComponent().velocity = v*5;
}
}
}
if (loopCnt <= 10)
{
GetComponent().velocity = new Vector2(-80,0);
}
else
{
GetComponent().velocity=Vector2.zero;
}
//float y=(Mathf.Sin(Mathf.Deg2Rad*loopCnt)+0.33f*Mathf.Sin(Mathf.Deg2Rad*loopCnt*3f))*5f+initPos.y;//フーリエ級数矩形波 第二項まで
float y = SquareWave(loopCnt * Mathf.Deg2Rad, 2)*5+initPos.y;
Vector2 pos=new Vector2(transform.position.x,y);
transform.position = pos;
loopCnt++;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "MyShot")
{
hp--;
}
}
float SquareWave(float rad,int terms)
{//矩形波をフーリエ展開し、ある項までで打ち切った結果を返す。(4/π は省略)
float result=0;
float magunitude;//角度についている係数
for (int i = 1; i <= terms; i++)
{
magunitude = (2 * i) - 1;
result += (1 / magunitude) * Mathf.Sin(magunitude * rad);
}
return result;
}
}