Created
October 2, 2023 06:55
-
-
Save satomi-i-k/0e097381d99c908907bc13d821b55d57 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine.UI; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
public class Raq_player : MonoBehaviour | |
{ | |
// MonoBehaviorのクラスを継承しているため、publicの変数はInspectorに表示され動的に変えることができる。 | |
// [HideInspector]で、外部クラスから値を参照するpublicの変数をInspectorに表示させないことができる | |
Vector3 target; | |
public Animator anim; | |
public Animator rangeCircle; | |
public Animator WiderangeCircle; | |
public Transform ball; | |
public Transform head; | |
public Transform lookAt; | |
public Transform opponent; | |
Vector3 startPos; | |
Vector3 startVelocity; | |
float startTime; | |
public float maxDragTime; | |
public float dragDistance; | |
public float speed; | |
public float timelag; | |
public float turnSpeed; | |
public float ballRange; | |
public float CeilingRange; | |
public float moveRange; | |
public float force; | |
public float upForce; | |
public float CeilingForce_y; | |
public float CeilingForce_z; | |
public float fowardForce; | |
public float swipeSensitivity; | |
public float frontwall_pos = 12.2f; // 前の壁のz座標の位置:ボールを打つ方向 | |
float rotation; | |
float ball_player_dist; | |
bool move_action; | |
bool right; | |
bool canShoot; | |
bool shoot = true; | |
bool isInactive; | |
bool isHitting; | |
public Raq_GameManager raq_GameManager; | |
Raq_GameManager gamemanagerScript; | |
RubberBall ballScript; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
raq_GameManager = GameObject.FindObjectOfType<Raq_GameManager>(); | |
gamemanagerScript = raq_GameManager.GetComponent<Raq_GameManager>(); | |
ballScript = ball.GetComponent<RubberBall>(); | |
isInactive = ball.GetComponent<RubberBall>().inactive; | |
rangeCircle.SetBool("Show", false); | |
WiderangeCircle.SetBool("Show", false); | |
isHitting = false; | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (Input.GetMouseButtonDown(0) && gamemanagerScript.playerServe && gamemanagerScript.befServe) | |
{ | |
StartCoroutine(Player_Serve()); | |
} | |
// set target as ball position | |
target = ball.position; | |
if (ball == null) | |
{ | |
return; | |
} | |
if (!gamemanagerScript.befServe && !ballScript.GetLastHit() && !ballScript.after_hit) | |
{ | |
//check if the player should move on the x axis | |
Raq_Move(); | |
//check if the ball is in range | |
Raq_CheckBallRange(); // ボールをhitできる状態であればそれを画面上で示す | |
//check if we can shoot | |
if (rangeCircle.GetBool("Show") || WiderangeCircle.GetBool("Show")) | |
{ | |
Raq_Shoot(); | |
} | |
} | |
else if (ballScript.GetLastHit() && rangeCircle.GetBool("Show") || WiderangeCircle.GetBool("Show")) | |
{ | |
rangeCircle.SetBool("Show", false); | |
WiderangeCircle.SetBool("Show", false); | |
} | |
} | |
void LateUpdate() | |
{ | |
head.LookAt(lookAt.position); | |
} | |
IEnumerator Player_Serve() | |
{ | |
anim.SetTrigger("Hit right"); | |
yield return new WaitForSeconds(0.28f); | |
EventManager.Instance.TriggerRaqplayerServe(); | |
ballScript.SetLastHit(true); // 最後に打った者をプレイヤーとして記録(アウト判定時の得点用) | |
} | |
//move left and right towards the target and update animations accordingly | |
void Raq_Move() | |
{ | |
float target_dist = Vector3.Distance(transform.position, target); | |
move_action = target_dist > 0.1f && !rangeCircle.GetBool("Show"); | |
if (move_action && !gamemanagerScript.befServe) | |
{ | |
Vector3 move_target = new Vector3(target.x - 0.02f, -2.5f, target.z); | |
transform.position = Vector3.MoveTowards(transform.position, move_target, Time.deltaTime * speed * 0.6f); // new player's position after moving | |
right = target.x < transform.position.x; // from opponent's view | |
} | |
if (anim.GetBool("Right") != right && !gamemanagerScript.befServe) // 右に行くべきなのにアニメーションが右方向への移動ではない | |
{ | |
anim.SetBool("Right", right); // 右に行くアニメーションにセット | |
} | |
if (gamemanagerScript.befServe) | |
{ | |
rotation = 0; | |
} | |
else | |
{ | |
if (right) | |
{ | |
rotation = -90; | |
} | |
else | |
{ | |
rotation = 91; | |
} | |
} | |
anim.SetBool("Moving", move_action && !gamemanagerScript.befServe); // 移動アニメーションにセット | |
Vector3 rot = transform.eulerAngles; // eulerAngles: オイラー角、絶対位置上の角度 | |
rot.y = rotation; // プレイヤーの方向を先ほどセットしたrotationの角度にするため | |
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rot), Time.deltaTime * turnSpeed); // 現在のrotationの値から先ほど更新した新しいrotationの値の角度に向かって Time.deltaTime * turnSpeed 回転 | |
} | |
//check if we can hit the ball | |
void Raq_CheckBallRange() | |
{ | |
if (ball == null) | |
{ | |
ball_player_dist = 0; | |
} | |
else | |
{ | |
ball_player_dist = Vector3.Distance(transform.position, ball.position); | |
} | |
if (ball_player_dist < ballRange && !isInactive) // ボールとプレイヤーの距離差が一定以下、ballがinactiveでない | |
{ | |
Raq_CanHitBall(); // ボールをhitできる状態であることを画面上で示すための関数 | |
if (WiderangeCircle.GetBool("Show")) | |
{ | |
WiderangeCircle.SetBool("Show", false); | |
} | |
} | |
else if (ball_player_dist < CeilingRange && !isInactive) // ボールとプレイヤーの距離差がシーリングが打てる状況 | |
{ | |
Raq_CanCeilingShot(); // シーリングショットできる状態を画面上で示すための関数 | |
if (rangeCircle.GetBool("Show")) | |
{ | |
rangeCircle.SetBool("Show", false); | |
} | |
} | |
else if (rangeCircle.GetBool("Show") || WiderangeCircle.GetBool("Show")) | |
{ | |
rangeCircle.SetBool("Show", false); // アニメーションの変更 | |
WiderangeCircle.SetBool("Show", false); | |
} | |
} | |
//if the ball is close enough, show the range circle | |
void Raq_CanHitBall() | |
{ | |
if (rangeCircle.GetBool("Show")) // rangeCircleのアニメーションがshowになっていれば終了、なっていなければshowに変える | |
return; | |
rangeCircle.SetBool("Show", true); | |
} | |
//if the ball is not close but can ceiling shot, show another range circle | |
void Raq_CanCeilingShot() | |
{ | |
if (WiderangeCircle.GetBool("Show")) // WiderangeCircleのアニメーションがshowになっていれば終了、なっていなければshowに変える | |
return; | |
WiderangeCircle.SetBool("Show", true); | |
} | |
// checks for swipe motion to see if we want to shoot the ball // 条件に合致すればRaq_Hit(currentPos)を発動 | |
void Raq_Shoot() | |
{ | |
Vector3 currentPos = Input.mousePosition; | |
if (Input.GetMouseButtonDown(0) && shoot) // ユーザーが左クリックしていればtrue、swipeがshootと扱われるための入口 | |
{ | |
canShoot = true; | |
startPos = currentPos; // 初期のマウス位置 | |
startTime = Time.time; // フレームの開始時間 | |
if (ball != null) | |
{ | |
// startVelocity = ball.GetComponent<Rigidbody>().velocity; | |
// ball.GetComponent<Rigidbody>().isKinematic = true; | |
} | |
} | |
else if (Input.GetMouseButton(0) && canShoot) | |
{ | |
if (Time.time - startTime > maxDragTime) // maxDragTimeはスワイプをshootとして判定する閾値、ドラッグの動きが遅いとshootにはならない | |
{ | |
Raq_ResetShot(); | |
} | |
else if (Vector3.Distance(startPos, currentPos) > dragDistance && !isHitting) // dragDistanceもスワイプをshootとして判定する閾値(距離だからfloat)。スワイプ距離が十分ならshootになる。 | |
{ | |
Raq_Hit(currentPos); | |
isHitting = true; | |
} | |
} | |
else if (Input.GetMouseButtonUp(0) && canShoot) // ユーザーが左クリックを離していればtrue | |
{ | |
Raq_ResetShot(); | |
} | |
} | |
//reset checks for swipe if swipe wasn't correct | |
void Raq_ResetShot() | |
{ | |
isHitting = false; | |
canShoot = false; // 入口に戻る | |
} | |
//hit the ball | |
void Raq_Hit(Vector3 currentPos) | |
{ | |
anim.SetTrigger("Hit right"); | |
//use the swipe to check the ball direction | |
float difference_x = currentPos.x - startPos.x; // マウスの移動距離(Shoot()が実行された時の差分) | |
float xPos = swipeSensitivity * -difference_x; // マウスの移動距離に係数をかける | |
float difference_y = currentPos.y - startPos.y; | |
float yPos = swipeSensitivity * -difference_y; | |
xPos = Mathf.Clamp(xPos, -moveRange, moveRange); // xPosの値の範囲を-制限し、一定以上の動きは同じものとして扱う | |
yPos = Mathf.Clamp(yPos, -moveRange, moveRange); | |
// ボールの移動先のベクトル | |
Vector3 random = new Vector3(xPos, yPos + ball.position.y, frontwall_pos) ; // 元のスクリプトではy=0. 後のvelocityの計算でy座標に一定の値が加えられている。これらを踏まえて確認。 | |
Vector3 direction = (random - transform.position).normalized; // プレイヤーがボールを打った方向の単位ベクトル | |
//check if this is the serve, or if we're just hitting the ball during the game and set the ball velocity | |
if (rangeCircle.GetBool("Show")) | |
{ | |
direction = new Vector3(direction.x * force, direction.y + upForce, direction.z * force * fowardForce); | |
} | |
else if (WiderangeCircle.GetBool("Show")) | |
{ | |
direction = new Vector3(direction.x * force, direction.z * force * CeilingForce_y, direction.z * force * CeilingForce_z); | |
} | |
EventManager.Instance.TriggerRaqplayerHit(direction); | |
ballScript.SetLastHit(true); // 最後に打った者をプレイヤーとして記録(アウト判定時の得点用) | |
} | |
//stop shooting for .7 seconds | |
IEnumerator Raq_DisableShooting() | |
{ | |
shoot = false; | |
yield return new WaitForSeconds(.7f); | |
shoot = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment