Created
November 16, 2023 23:41
-
-
Save ryogrid/8f9d717c694dbbc1bb673c31e9346999 to your computer and use it in GitHub Desktop.
Unityで作った3D版Pongのソースコード部分だけ (https://unityroom.com/games/3dpongmodoki)
This file contains hidden or 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; | |
public class BallController : MonoBehaviour | |
{ | |
public GameObject StampPrefab; | |
public GameObject ParticlePrefab; | |
private Rigidbody rb; | |
private GameObject BallZLine; | |
private GameObject BallZLineHorizontal; | |
private GameObject BallZLineVertical; | |
private Vector3 lastVelocity; | |
private Vector3 lastPosition; | |
private int counter = 0; | |
public static float Z_CONSTANT_VELOCITY = 2.5f; | |
private const float Z_CONSTANT_HALF_VELOCITY = 1.25f; | |
private const float Z_STRANGE_VELOCITY_THRESHOLD = 0.1f; | |
private const float XY_VELOCITY_LATIO_UPPER = 1f; | |
private const float XY_VELOCITY_LATIO_BOTTOM = 0.2f; | |
private AudioSource audioSource; | |
public AudioClip audioBound; | |
private const int COUNTER_ADJUST_THRESHOLD = 5; | |
private GameObject createdParticle = null; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
lastVelocity = new Vector3(0, 0, 0); | |
rb = this.GetComponent<Rigidbody>(); | |
BallZLine = GameObject.Find("BallZLine"); | |
BallZLineHorizontal = GameObject.Find("BallZLineHorizontal"); | |
BallZLineVertical = GameObject.Find("BallZLineVertical"); | |
audioSource = gameObject.GetComponent<AudioSource>(); | |
} | |
//一定秒数ごとに呼び出される. デフォルトは20ms間隔らしい | |
void FixedUpdate() | |
{ | |
if (counter > COUNTER_ADJUST_THRESHOLD) | |
{ | |
//ボールのスピードをいい感じに調整する | |
adjustBallSpeed(); | |
} | |
//異様に速度が遅くなっている場合はその速度は採用しない | |
if(Mathf.Abs(rb.velocity.z) >= Z_CONSTANT_HALF_VELOCITY || counter < COUNTER_ADJUST_THRESHOLD) | |
{ | |
lastVelocity = rb.velocity; | |
} | |
//iTween.MoveTo(BallZLine, iTween.Hash("x", this.transform.position.x, "y", this.transform.position.y)); | |
BallZLine.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, 0); | |
BallZLineHorizontal.transform.position = new Vector3(0, this.transform.position.y, this.transform.position.z); | |
BallZLineVertical.transform.position = new Vector3(this.transform.position.x, 0, this.transform.position.z); | |
} | |
private void resetBallZLine() | |
{ | |
BallZLine.transform.position = new Vector3(0, 0, 0); | |
BallZLineHorizontal.transform.position = new Vector3(0, 0, 0); | |
BallZLineVertical.transform.position = new Vector3(0, 0, 0); | |
} | |
private void adjustBallSpeed() | |
{ | |
float vx = rb.velocity.x; | |
float vy = rb.velocity.y; | |
float vz = rb.velocity.z; | |
float vz_abs = Mathf.Abs(vz); | |
if (vz_abs <= Z_STRANGE_VELOCITY_THRESHOLD && counter > COUNTER_ADJUST_THRESHOLD) { | |
// 突き抜け等の可能性があるため必ず手前方向に移動させる | |
vz_abs = Z_CONSTANT_VELOCITY; | |
vz = -1 * Z_CONSTANT_VELOCITY; | |
} | |
if (vz_abs < Z_CONSTANT_VELOCITY){ | |
vz_abs = Z_CONSTANT_VELOCITY; | |
vz = vz >= 0 ? Z_CONSTANT_VELOCITY : -1 * Z_CONSTANT_VELOCITY; | |
} | |
if(Mathf.Abs(vx) >= XY_VELOCITY_LATIO_UPPER * vz_abs) | |
{ | |
vx = vx >= 0 ? XY_VELOCITY_LATIO_UPPER * vz_abs : -1 * XY_VELOCITY_LATIO_UPPER * vz_abs; | |
} | |
if(Mathf.Abs(vx) <= XY_VELOCITY_LATIO_BOTTOM * vz_abs) | |
{ | |
vx = vx >= 0 ? XY_VELOCITY_LATIO_BOTTOM * vz_abs : -1 * XY_VELOCITY_LATIO_BOTTOM * vz_abs; | |
} | |
if(Mathf.Abs(vy) >= XY_VELOCITY_LATIO_UPPER * vz_abs) | |
{ | |
vy = vy >= 0 ? XY_VELOCITY_LATIO_UPPER * vz_abs : -1 * XY_VELOCITY_LATIO_UPPER * vz_abs; | |
} | |
if(Mathf.Abs(vy) <= XY_VELOCITY_LATIO_BOTTOM * vz_abs) | |
{ | |
vy = vy >= 0 ? XY_VELOCITY_LATIO_BOTTOM * vz_abs : -1 * XY_VELOCITY_LATIO_BOTTOM * vz_abs; | |
} | |
rb.velocity = new Vector3(vx, vy, vz); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (transform.position.z < -3f) | |
{ | |
resetBallZLine(); | |
Destroy(gameObject); | |
} | |
counter += 1; | |
if((lastPosition == null || counter % 11 == 0)) | |
{ | |
lastPosition = gameObject.transform.position; | |
} | |
if (counter % 17 == 0 && lastPosition.x == gameObject.transform.position.x && lastPosition.y == gameObject.transform.position.y && lastPosition.z == gameObject.transform.position.z | |
&& rb.velocity.x == 0 && rb.velocity.x == 0 && rb.velocity.z == 0){ | |
resetBallZLine(); | |
Destroy(gameObject); | |
} | |
} | |
void createStamp(Collision coll) | |
{ | |
float x = gameObject.transform.position.x; | |
float y = gameObject.transform.position.y; | |
float z = gameObject.transform.position.z; | |
//当たり判定が発生した座標 | |
Vector3 contactCood = coll.GetContact(0).point; | |
float cx = contactCood.x; | |
float cy = contactCood.y; | |
float cz = contactCood.z; | |
GameObject wall = coll.gameObject; | |
float wx = wall.transform.position.x; | |
float wy = wall.transform.position.y; | |
float wz = wall.transform.position.z; | |
// 0.1fは差が明確にあることを判定するために適当に選んだ閾値 | |
if(createdParticle != null) | |
{ | |
Destroy(createdParticle); | |
} | |
if(Mathf.Abs(cx) - Mathf.Abs(x) > 0.1f) //左右の壁 | |
{ | |
GameObject obj = Instantiate(StampPrefab, new Vector3(wx, y, z), Quaternion.identity); | |
createdParticle = Instantiate(ParticlePrefab, new Vector3(cx, y, z), Quaternion.identity); | |
obj.transform.rotation = Quaternion.Euler(0, 0, 90) * obj.transform.rotation; | |
return; | |
} | |
if(Mathf.Abs(cy) - Mathf.Abs(y) > 0.1f) //上下の壁 | |
{ | |
GameObject obj = Instantiate(StampPrefab, new Vector3(x, wy, z), Quaternion.identity); | |
createdParticle = Instantiate(ParticlePrefab, new Vector3(x, cy, z), Quaternion.identity); | |
return; | |
} | |
if(Mathf.Abs(cz) - Mathf.Abs(z) > 0.1f) //奥の壁もしくはラケット | |
{ | |
if(z > 0) //奥の壁 | |
{ | |
GameObject obj = Instantiate(StampPrefab, new Vector3(x, y, wz), Quaternion.identity); | |
createdParticle = Instantiate(ParticlePrefab, new Vector3(x, y, cz), Quaternion.identity); | |
obj.transform.rotation = Quaternion.Euler(90, 0, 0) * obj.transform.rotation; | |
return; | |
} | |
else //ラケット | |
{ | |
GameObject obj = Instantiate(StampPrefab, new Vector3(x, y, wz), Quaternion.identity); | |
//薄くする | |
obj.transform.localScale = new Vector3(0.3f, 0.001f, 0.3f); | |
obj.transform.rotation = Quaternion.Euler(90, 0, 0) * obj.transform.rotation; | |
return; | |
} | |
} | |
} | |
void OnCollisionEnter(Collision coll) | |
{ | |
Vector3 refrectVec = Vector3.Reflect(this.lastVelocity, coll.contacts[0].normal); | |
//Debug.Log(refrectVec); | |
refrectVec.x *= 1.01f; | |
refrectVec.y *= 1.01f; | |
refrectVec.z *= 1.01f; | |
rb.velocity = refrectVec; | |
createStamp(coll); | |
audioSource.PlayOneShot(audioBound); | |
} | |
} |
This file contains hidden or 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; | |
using UnityEngine.UI; | |
public class KeyCheckerControler : MonoBehaviour | |
{ | |
public GameObject BallPrefab; | |
public GameObject RacketPrefab; | |
private GameObject ScoreText; | |
private GameObject createdBall = null; | |
private GameObject createdRacket = null; | |
private GameObject RacketZLineHorizontal = null; | |
private GameObject RacketZLineVertical = null; | |
private const float CHECK_INTERVAL = 0.01f; | |
private const float MOVE_DISTANCE = 0.05f; | |
private const float PIXCELS_OF_UNIT = 100f; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
createdRacket = Instantiate(RacketPrefab, new Vector3(0, 0, -2f), Quaternion.identity); | |
ScoreText = GameObject.Find("ScoreMeshText"); | |
ScoreText.GetComponent<TextMesh>().text = "0 回"; | |
RacketZLineHorizontal = GameObject.Find("RacketZLineHorizontal"); | |
RacketZLineVertical = GameObject.Find("RacketZLineVertical"); | |
//createdRacket.GetComponent<Renderer>().material.color = Color.blue; | |
InvokeRepeating("checkKeyPress", CHECK_INTERVAL, CHECK_INTERVAL); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
} | |
float getConvertedMouseCoodX() | |
{ | |
return ((Input.mousePosition.x / Screen.width) * 5f - 2.5f) * 1.3f; | |
} | |
float getConvertedMouseCoodY() | |
{ | |
return (Input.mousePosition.y / Screen.height) * 5f - 2.5f; | |
} | |
void checkKeyPress() | |
{ | |
createdRacket.transform.position = new Vector3 (getConvertedMouseCoodX(), getConvertedMouseCoodY(), createdRacket.transform.position.z); | |
if (Input.GetKeyDown(KeyCode.Space)) | |
{ | |
shotNewBall(); | |
} | |
RacketZLineHorizontal.transform.position = new Vector3(0, createdRacket.transform.position.y, createdRacket.transform.position.z); | |
RacketZLineVertical.transform.position = new Vector3(createdRacket.transform.position.x, 0, createdRacket.transform.position.z); | |
} | |
private void reCreateRacket() | |
{ | |
if(createdRacket != null) | |
{ | |
Destroy(createdRacket); | |
createdRacket = null; | |
} | |
createdRacket = Instantiate(RacketPrefab, new Vector3(0, 0, -2f), Quaternion.identity); | |
} | |
void shotNewBall() | |
{ | |
if (createdBall != null) | |
{ | |
return; | |
} | |
createdBall = Instantiate(BallPrefab, new Vector3(0, 0, -1.5f), Quaternion.identity); | |
float shotVerocityFixedZ = BallController.Z_CONSTANT_VELOCITY; | |
float shotAngle = Random.Range(0f, 360f); | |
float x_speed = Mathf.Cos(2 * Mathf.PI * (shotAngle / 360f)) * shotVerocityFixedZ; | |
float y_speed = Mathf.Sin(2 * Mathf.PI * (shotAngle / 360f)) * shotVerocityFixedZ; | |
createdBall.GetComponent<Renderer>().material.color = Color.black; | |
//createdBall.GetComponent<Rigidbody>().AddForce(new Vector3(x_power, y_power, shotVerocityFixedZ)); | |
createdBall.GetComponent<Rigidbody>().velocity = new Vector3(x_speed, y_speed, shotVerocityFixedZ); | |
//createdBall.GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, shotPowerFixedZ)); | |
ScoreText.GetComponent<TextMesh>().text = "0 回"; | |
//内部状態を初期化するために作り直す | |
reCreateRacket(); | |
} | |
} |
This file contains hidden or 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; | |
public class RacketController : MonoBehaviour | |
{ | |
private int BoundCount; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
BoundCount = 0; | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
} | |
void OnCollisionEnter(Collision collision) | |
{ | |
BoundCount++; | |
GameObject.Find("ScoreMeshText").GetComponent<TextMesh>().text = BoundCount.ToString() + " 回"; | |
} | |
} |
This file contains hidden or 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; | |
public class StampController : MonoBehaviour | |
{ | |
private int counter = 0; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
//if(counter > 50) | |
if(counter > 15) | |
{ | |
Destroy(gameObject); | |
return; | |
} | |
counter++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment