Unity

ステージを移動するコライダーを作る

using System;
using UnityEngine;

public class Warp : MonoBehaviour
{
public Transform warpTarget;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{

}

// Update is called once per frame
void Update()
{

}

private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
other.transform.position = warpTarget.position;
}
}
}

移動させたい場所にGameObjectを作成し、それをC#のコンポーネントのところに設定する

PlayerとBlockとSwitchとDoorをPrefabにする

5月29日(木)

ブロックの横のところでジャンプをして、張り付いてから降りると、ジャンプができなくなる現象が起こっていたのでそれを直す

大きいところはTagをUntaggedにし、オブジェクトはTagはBlockにする。オブジェクトを分け、上のオブジェクトを少しだけ小さくして、下のオブジェクトも同じように少しだけ小さくする

これで直る!

ワープするとジャンプができなくなることに気がついたので直す!

Playerのコードにこれを追加する!

public void Ground()
{
isGrounded = true;
}

ワープのコードに

[SerializeField] public Player[] players;

foreach (var player in players)
{
player.Ground();
}

を追加!

Playerコード完全版

using UnityEngine;

public class Player : MonoBehaviour
{
[SerializeField] private float moveSpeed; // 移動速度
[SerializeField] private float jumpForce; // ジャンプ力
[SerializeField] private float deadZone = 0.1f; // コントローラーのデッドゾーン
private Rigidbody rb; // プレイヤーのRigidbody
private bool isGrounded; // 地面に接しているかどうか

void Start()
{
rb = GetComponent<Rigidbody>();
}

void Update()
{
Move();
Jump();
}

void Move()
{
Vector3 moveDirection = Vector3.zero;

// キーボード入力
if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
{
moveDirection += transform.forward;
}
if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))
{
moveDirection -= transform.forward;
}
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
{
moveDirection -= transform.right;
}
if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
{
moveDirection += transform.right;
}

// コントローラー入力(左スティック)
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");

// デッドゾーン処理
if (Mathf.Abs(horizontal) > deadZone)
{
moveDirection += transform.right * horizontal;
}
if (Mathf.Abs(vertical) > deadZone)
{
moveDirection += transform.forward * vertical;
}

Vector3 move = moveDirection.normalized * moveSpeed;
Vector3 velocity = rb.linearVelocity;
rb.linearVelocity = new Vector3(move.x, velocity.y, move.z);
}

void Jump()
{
// キーボード(スペースキー)またはコントローラー(×ボタン)でジャンプ
if ((Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Joystick1Button1)) && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
}

void OnCollisionEnter(Collision collision)
{
// 地面に着いたらジャンプ可能にする
if (collision.gameObject.CompareTag("Ground") || collision.gameObject.CompareTag("Block"))
{
isGrounded = true;
}
}

public void Ground()
{
isGrounded = true;
}
}

Warpコード完全版

using System;
using UnityEngine;

public class Warp : MonoBehaviour
{
public Transform warpTarget;
[SerializeField] public Player[] players;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{

}

// Update is called once per frame
void Update()
{

}

public void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
other.transform.position = warpTarget.position;
foreach (var player in players)
{
player.Ground();
}
}
}
}

直った!!

ステージを二つ作った!

右側の上のところに浮いているのは、TagにGroundというふうにつける

BlockのMASSを7にする

5月30日(金)

浮いているブロックのところに柱をつける

エレベーターを作る!

でもエラーが発生したため、次の日までかかってしまいました

5月31日(土)

エレベーターが動いたため、プログラムを出します

ElevatorスクリプトとElevatorSwitchスクリプトの二つを作成

Elevatorスクリプト

using System.Collections;
using UnityEngine;

public class Elevator : MonoBehaviour
{
[SerializeField] private float moveSpeed = 2f; // 移動速度
[SerializeField] private float arrivalThreshold = 0.01f; // 到着とみなす距離
[SerializeField] private float waitTime = 5f; // 待機時間
[SerializeField] public ElevatorSwitch[] elevators; // スイッチと連携する場合用
public Transform targetTransform; // 目的地(上の位置)
public Vector3 startPosition; // 初期位置(下の位置)

private bool isMoving = false; // 移動中フラグ
private bool isAtTop = false; // 上にいるかどうか

void Start()
{
startPosition = transform.position;
// 初期状態では停止している
isMoving = false;
isAtTop = false;
}

void Update()
{
if (isMoving && targetTransform != null)
{
Vector3 destination = isAtTop ? startPosition : targetTransform.position;

transform.position = Vector3.MoveTowards(
transform.position,
destination,
moveSpeed * Time.deltaTime
);

if (Vector3.Distance(transform.position, destination) < arrivalThreshold)
{
transform.position = destination;
isMoving = false;

if (!isAtTop)
{
// 上に到着した場合:待機してから下に戻る
isAtTop = true;
StartCoroutine(WaitAndMoveDown());
}
else
{
// 下に到着した場合:スイッチのクリックを再び許可
isAtTop = false;
EnableSwitches();
}
}
}
}

private IEnumerator WaitAndMoveDown()
{
yield return new WaitForSeconds(waitTime);

// 自動的に下に移動開始
isMoving = true;
}

private void EnableSwitches()
{
// スイッチのクリックを再び許可する
foreach (var elevatorSwitch in elevators)
{
elevatorSwitch.EnableClick();
}
}

// 外部から呼び出して上への移動開始
public void MoveUp()
{
if (targetTransform != null && !isMoving && !isAtTop)
{
isMoving = true;
}
}
}

ElevatorSwitchスクリプト

using UnityEngine;

public class ElevatorSwitch : MonoBehaviour
{
[SerializeField] public Elevator[] elevators;
private bool canClick = true;

void Update()
{
if (Input.GetMouseButtonDown(0) && canClick)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (hit.collider.gameObject == gameObject)
{
Debug.Log("エレベータースイッチがクリックされました: " + gameObject.name);
canClick = false;

// 全てのエレベーターを上に移動させる
foreach (var elevator in elevators)
{
elevator.MoveUp();
}
}
}
}
}

// Elevator から呼ばれてクリック許可を戻す
public void EnableClick()
{
canClick = true;
Debug.Log("エレベータースイッチが再び使用可能になりました: " + gameObject.name);
}
}

Elevatorコンポーネント

ElevatorSwitchコンポーネント

Elevatorコンポーネントでは、上から、

MoveSpeed 移動速度

ArrivalThreshold 間隔の時間(0.01のままでOK)

WaitTime 秒数

Elevators ElevatorSwitchを入れてください

TargetTransform 目的地 GameObjectを分けてください

StartPosition エレベーターの最初のポジションを入れてください

ElevatorSwitchコンポーネントでは、

Elevators 発動させるエレベーターを入れてください

上から、

Elevatorが動くエレベーター ここにElevatorスクリプトを入れる

ElevatorSwitchがElevatorSwitchをまとめるGameObject

Switchが押されたら発動する ここにElevatorSwitchスクリプトを入れる

Cubeは見た目でつける

ElevatorPositionがエレベーターの目的地です