using UnityEngine;
using UnityEngine.Tilemaps;
public class Box : MonoBehaviour
{
const float Gravity = -0.01f;
const float OffsetY = -0.5f;
const int StrCut = 8;
const float TAnker = 0.5f;
[SerializeField]
Tilemap tilemap;
Time60 time60;
Vector3 pos;
Vector3Int gridPos;
Vector3 speed = new Vector3();
Vector2[] line = new Vector2[2];
int index = 0; //タイル(スプライト)の番号
float dist = 0; //めり込んだ長さ
float px = 0;
float py = 0;
string str = ""; //テキスト表示用
bool isGround = false;
public string sText;
// Start is called before the first frame update
void Start()
{
GameObject time60Obj = GameObject.Find("Time60");
time60 = time60Obj.GetComponent<Time60>();
pos = this.transform.position;
speed = Vector3.zero;
}
// Update is called once per frame
void Update()
{
dist = 0;
// 1/60秒ごとに処理をするための門番
if( time60.CheckFlame() != true) return;
//現在位置を受け取る
pos = this.transform.position;
//ボックスの横移動量
speed.x = 0.01f;
//ボックスの自由落下量
speed.y = speed.y + Gravity;
//接地状態では、Y方向の移動量をゼロにする
if( isGround == true) speed.y = 0;
//まず、座標の仮移動
pos.x = pos.x + speed.x;
pos.y = pos.y + speed.y;
//接地フラグをクリアする
isGround = false;
//今の場所のタイルの種類の番号を得る(1回目)
index = this.CheckTerrain(pos);
//タイルのローカル座標を得る(1回目)
px = pos.x % 1;
py = pos.y % 1;
//まず、進入禁止を判定
if( index == 1){
line[0].x = gridPos.x;
line[0].y = gridPos.y;
line[1].x = gridPos.x + 1.0f;
line[1].y = gridPos.y;
//線分と現在座標の関係をチェックする
dist = CheckLine( pos, line, 0);
//接地フラグ
isGround = true;
//Y座標を補正
pos.y = pos.y + dist;
}
//補正後再びびチェックする----------------------------------
dist = 0;
//今の場所のタイルの種類の番号を得る(2回目)
index = this.CheckTerrain(pos);
//タイルのローカル座標を得る(2回目)
px = pos.x % 1;
py = pos.y % 1;
//タイルの種類ごとに処理を分ける
switch(index){
case 0:
break;
case 1: //進入禁止
break;
case 2: //上り45度
//線分の始点と終点を決める
line[0].x = gridPos.x;
line[0].y = gridPos.y;
line[1].x = gridPos.x + 1.0f;
line[1].y = gridPos.y + 1.0f;
//線分と現在座標の関係をチェックする
dist = CheckLine( pos, line, 0);
break;
default:
dist = 0;
break;
}
if( dist < 0){
//接地フラグを立てる
isGround = true;
}
//地形にめり込んだ長さを戻す
pos.y = pos.y - dist;
transform.position = pos;
}
//地形の線分より下にあるか調べ、その長さを返す
private float CheckLine( Vector3 _cPos, Vector2[] _line,float _offsetY){
bool inv = false; //上り下り反転フラグ
float ret = 0;
float x1 = 0;
float y1 = 0;
px = _cPos.x % 1;
py = _cPos.y % 1;
//Y軸の距離を出す
y1 = _line[1].y - _line[0].y;
//平行の場合
if( y1 == 0) return 1 - py;
//下り坂ならフラグを立てる
if( y1 < 0) inv = true;
//X軸の距離を出す
x1 = _line[1].x - _line[0].x;
//上り坂の場合(高さが+)
if( inv != true){
//Y位置と線分の高さを計算する
ret = py - (y1 / x1) * px + _offsetY;
if( ret > 0)
return 0;
return ret;
}
//Y位置と線分の高さを計算する
ret = py - (y1 / x1) * px - _offsetY;
//下り坂の場合(高さが-)
if( ret > 0)
return 0;
return ret;
}
//指定の場所が地形その他の当たり判定に重なっているか?
private int CheckTerrain(Vector3 _checkPos)
{
int number;
//グリッド座標に変換する
Vector3Int targetPosInt = tilemap.WorldToCell(_checkPos);
//グリッド座標のスプライト情報を取得する
Sprite spr = tilemap.GetSprite(targetPosInt);
if(spr != null)
str = spr.name.Substring( 8, spr.name.Length - 8); //"Terrain_"の文字を取り除く
else
str = "-1";
//Int型に変換
number = int.Parse(str);
if( number > -1){
return number;
}
return -1;
}