よく2Dゲームで見られる放物線に基づくの遊び方。
1.先ず、Unity Hubを起動して、新しい2Dプロジェクトを新規作成してください。<2019.4.22f1使ってるけど、最新のバージョンをインストールして使ってください>
2.地面を作る
Hierarchy内に2D object >Sprite>Squareを作成して、座標Resetして、名前DragPointにする名前はGroundにする、それからInspectorでLayerを一つ追加して、名前もGroundにして選択してください。colorやsizeは適当にしておいて。Ground選択して、Rigidbody2DとBOXCollider2Dを追加して、Rigidbody2DのBady TypeをStaticに、以上したら地面の準備完了。
3.軌跡線現すためのGameObjectを作ります
空オブジェクトを作成して、座標Resetして、名前はLine1にして、InspectorでLine Rendererを追加してください。ProjectでNew Materialを作って、選択した状態でInspectorでのShaderのタイプはGUIにして、素材line-untiyのテクスチャをFont Textureにアタッチして、Tilingxを和4にする。効果は以下の図を見てください。
そしてLine1を選択し、Line RendererのPositionsでのSizeのXの二行目を5にして、Texture ModeをTileにして、Widthを0.1にすれば良いと思います。先ほど作ってたNew MaterialをLine RendererのMaterialsにアタッチしてcolorクリックして右上の矢印ボタンを選択してAlphaを0にする、Additional SettingsでOrder in Layerを1にしてOKです。
4.力加減線を現すGameObject
空オブジェクトを作成して、座標Reset、名前はLine2にして、InspectorでLine Rendererを追加してください。PositionsでのSizeのXの二行目を-1.5ぐらいにして、Widthを0.05にする、MaterialsはDefault-Lineにして、Order in Layerを1に、ほぼLine1と同じ操作です。
5.球を作ります
空オブジェクトを作成して、座標Resetして、名前Ballにする、素材バスケットボールをInspectorでのSpriteにアタッチする、sizeを適用に調整して、Additional SettingsでOrder in Layerを2に、Rigidbody2DとCircle Collider2Dを追加して、ProjectにCreate>2D>Physics Material2Dを作成して、Bouncinessを0.3にする、それをBallのCircle Collider2DのMaterialにアタッチして、Rigidbody2DのGravity Scaleを0に、Collision DetectionをContinuousにする。
6.引っ張れる点
Hierarchy内に2D object >Sprite>Circleを作成して、座標Resetして、名前DragPointにする、Sizeは適当に、Additional SettingsでOrder in Layerを1に、これで終わり、
7.コード
Parabola CTRLのScriptをBallにアタッチして、Line1にLine1GameObjectを入れて、Line2も同様、Line1Numをに20、Max Forceに2、Release Forceに6、GroundにGroundアタッチして、GroundLayerをGroundに選択して、DragPointに先作ったのを入れて。実行してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.EventSystems;
public class parabolaCTRL : MonoBehaviour
{
private Vector2 mouse_Pos; //マウス位置の世界座標
public LineRenderer line1; //軌跡線
public int line1Num = 10; //Line Renderの線分の数
Vector3 points1; //軌跡の配列値
public LineRenderer line2; //力加減線
public float maxForce = 2; //最大力加減
int line2Num = 2; //Line Renderの線分の数
Vector3 points2; //力加減の配列値
Rigidbody2D rb2D; //球のRigidbody2D
public float releaseForce; //限外の力
Vector2 release_Velocity; //初速度
float S; //最大の水平距離
float t; //水平飛ぶ時間
float g = 9.8f; //重力加速度
public Transform ground; //地面
float height; //地面から球までの高さ
float xUnit = .1f; //X軸の描く間隔
//地面Layer
public LayerMask groundLayer;
//引っ張れる点
public GameObject dragPoint;
//軌跡線の始点の色
Vector4 fadeLine = new Vector4(1,1,1,1);
enum STATE
{
NONE = -1,
IDLE = 0, //静止
GRAB, //触る
DRAG, //引っ張る
RELEASE, //手離す
LAND, //着地
NUM,
}
private STATE state = STATE.IDLE; //最初の状態
private STATE next_state = STATE.NONE; //次の状態
private void Start()
{
//Line Renderの線分の数を設定する<Unity API>
line1.positionCount = line1Num;
line2.positionCount = line2Num;
//線分の数によって、配列値を決める
points1 = new Vector3[line1Num];
points2 = new Vector3[line2Num];
//Rigidbody2D
rb2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
//マウス位置の世界座標を読み込み
mouse_Pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//-------------------状態変更---------------------------------------
switch (state)
{
//手離すの状態下で,地面に検測したら,着地の状態に変更。
case STATE.RELEASE:
if (rb2D.IsTouchingLayers(groundLayer) && rb2D.velocity.y == 0)
next_state = STATE.LAND;
break;
//着地の状態で,もし球が静止になったら,静止状態に変更
case STATE.LAND:
if (rb2D.velocity == Vector2.zero)
next_state = STATE.IDLE;
break;
}
//---------------------状態初期化------------------------------------------
//状態変更する場合、一回だけ行い
if (next_state != STATE.NONE)
{
//状態変更
state = next_state;
next_state = STATE.NONE;
switch (state)
{
//触る時に
case STATE.GRAB:
rb2D.gravityScale = 0; //重力影響を0に
height = transform.position.y - ground.position.y; //地面から球までの高さを取り
line1.startColor = new Vector4(1, 1, 1, 1); //改めて軌跡線を現す
line2.enabled = true;
dragPoint.SetActive(true);
next_state = STATE.DRAG; //引っ張る状態に入りの準備をする
break;
//手離す時に
case STATE.RELEASE:
//球のRigidbody2Dのプロパティの調整
rb2D.drag = 0; //抗力
rb2D.gravityScale = 1 ; //重力
rb2D.velocity = release_Velocity;//初速度
line2.enabled = false; //力加減線を隠す
dragPoint.SetActive(false);
break;
//着地状態に入る時
case STATE.LAND:
//球を止めるため、抗力を少しアップします
rb2D.drag = 0.8f;
break;
}
}
//------------------------状態の行い-------------------------------------
switch (state)
{
case STATE.DRAG:
//###引っ張る時に線分を現す###
//マウスと球の位置を繋ぐ線分
points2[0] = transform.position;
points2[1] = mouse_Pos;
//もし最長を超えたら,最長になる
if (Vector3.Distance(points2[0], points2[1]) > maxForce)
{
points2[1] = points2[0] + (points2[1] - points2[0]).normalized * maxForce;
}
line2.SetPositions(points2);
//末端にある引っ張れる点の位置
dragPoint.transform.position = points2[1];
//###軌跡放物線###
//初速度
release_Velocity = (points2[0] - points2[1]) * releaseForce;
//着地から最大水平移動距離
S = release_Velocity.x * (release_Velocity.y / g + Mathf.Sqrt*1;
//水平移動によって、軌跡のX軸の描く間隔を確認する
xUnit = S / line1Num;
//LineRenderを結合して画像を描く
for (int i = 0; i < line1Num; i++)
{
points1[i].x = transform.position.x + i * xUnit;
points1[i].y = GetFuncPathY(points1[i].x);
}
line1.SetPositions(points1);
break;
case STATE.RELEASE:
//軌跡線が徐々に消える
fadeLine.w -= Time.deltaTime * 2;
Mathf.Clamp01(fadeLine.w);
line1.startColor = fadeLine;
break;
}
}
//マウス押すと,触る状態になる
private void OnMouseDown()
{
next_state = STATE.GRAB;
}
//でないと,手離す状態になる
private void OnMouseUp()
{
next_state = STATE.RELEASE;
}
//Y座標関数を取る。>放物線の軌跡方程式<
float GetFuncPathY(float x)
{
float y;
y = (release_Velocity.y / release_Velocity.x) * (x - transform.position.x) - (g * (x - transform.position.x) * (x - transform.position.x)) / (2 * release_Velocity.x * release_Velocity.x) + transform.position.y;
return y;
}
}
以上です。
素材やコードなどまとめています
<下手ですが、コードの注釈を日本語に翻訳しました>
drive.google.com
ビリビリ動画から運んできました。自分のものではありません。もし権利侵害したら、連絡してください、削除します。www.bilibili.com
*1:release_Velocity.y * release_Velocity.y / g / g) + 2 * height / g
Unityでダメージを受けたキャラのHPバーの作り方を紹介します!
1.先ずはUnity開いて、今回もは2Dオブジェクトで作成して名前はHealthBarにします。
2.開いたら、HierarchyでCanvasを追加してから空オブジェクトを作って、座標Resetして、名前はHealthBarにします、右クリックして、UI>imageをそのHealthBarの子供にして、名前はHealthにします。imageのSourceImageに素材5をアタッチして、ImageTypeはFilledで、FillMethodはHorizontalして、SetNativeSizeをクリック。
3.また、HealthBarの下でHealthと同じImageを作って、名前はBGにします。今回は素材4をSourceImageにアタッチしてから、直接SetNativeSizeをクリックしてください。
4.Healthをコピーして、名前はHealthFadeにします、Colorだけ不透明度を本来の半分にします。
5.GameManagerを作ります、座標Resetして、二つのコードをアタッチします。図のように:
画面をクリックすれば以下のような効果ができます!
コード以下:
HealthBarCTRL
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthBarCTRL : MonoBehaviour
{
public Image health_image;
public Image health_fade;
private void Update()
{
health_image.fillAmount = HealthPointCTRL.health_point / 100f;
health_fade.fillAmount = HealthPointCTRL.fade_health_point / 100f;
}
}
HealthPointCTRL
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HealthPointCTRL : MonoBehaviour
{
public static float health_point, fade_health_point;
float fade_Timer = 0;
public float fade_Time=1f;
Coroutine damage_Coroutine = null;
private void Awake()
{
health_point = 100f;
fade_health_point = 100f;
}
private void Update()
{
if(Input.GetMouseButtonDown(0))
{
fade_Timer = 0;
Damage_Once(10);
}
else if(Input.GetMouseButtonDown(1))
{
if(damage_Coroutine!=null)
{
StopCoroutine(damage_Coroutine);
damage_Coroutine = StartCoroutine(Damage_Over_Time(5, 2));
}
else
{
damage_Coroutine = StartCoroutine(Damage_Over_Time(5, 2));
}
fade_Timer += Time.deltaTime;
if(fade_health_point>health_point&&fade_Timer>fade_Time)
{
fade_health_point = Mathf.Lerp(fade_health_point, health_point, Time.deltaTime * 2);
}
}
}
public void Damage_Once(float damage)
{
health_point -= damage;
}
public IEnumerator Damage_Over_Time(float damage, float duration)
{
float timer = 0;
while(health_point>=0&&timer<=duration)
{
health_point -= damage * Time.deltaTime;
timer += Time.deltaTime;
yield return null;
}
}
}
ビリビリ動画から運んできました。自分のものではありません。もし権利侵害したら、連絡してください、削除します。