ºÇ½ª¹¹¿·¡§
orika_ex_miyako 2024ǯ04·î15Æü(·î) 14:10:46ÍúÎò
°ìÄê»þ´Ö·Ð²á¤´¤È¤Ë»ØÄꤷ¤¿ÈÏ°ÏÆâ¤Ë¹¶·âÂоݤ¬¤¤¤ë¤³¤È¤ò³Îǧ¤·¡¢Âоݤ¬¤¤¤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤Î¤¦¤Á¤ÎºÇ¤â¥×¥ì¥¤¥ä¡¼¤Ë¶á¤¤ÂоݤË1²ó¹¶·â¤ò¹Ô¤¤¤Þ¤¹¡£
¤³¤ì¤ò¼«Æ°Åª¤Ë·«¤êÊÖ¤·¤Þ¤¹¡£
¡¡
¡¡±þÍѤ¹¤ë¤³¤È¤Ç¥ô¥¡¥ó¥Ñ¥¤¥¢¥µ¥Ð¥¤¥Ð¡¼¥º¤ä¥¢¡¼¥Á¥ã¡¼ÅÁÀâ¤Ê¤É¤Î¤è¤¦¤Ê¥ª¡¼¥È¥Ð¥È¥ë¥·¥¹¥Æ¥à¤Îº¬´´¤È¤·¤ÆÍøÍѲÄǽ¤Ç¤¹¡£
¡¡¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È´ðÄ쥯¥é¥¹¤òºîÀ®¤·¤¿¾å¡¢MVP ¥Ñ¥¿¡¼¥ó¤òºÎÍѤ·¡¢Model¡¢View¡¢Presenter ¤Î£³¤Ä¤òºîÀ®¤·¤Þ¤¹¡£
using UnityEngine;
/// <summary>
/// ½é´üÀßÄ궦Ä̲½ÍѤΥ¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹
/// </summary>
public interface ISetup {
void SetUp(GameObject entityObject = null);
}
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
/// <summary>
/// Slider ÍÑ´ðÄ쥯¥é¥¹
/// </summary>
public class BarBase : MonoBehaviour {
#pragma warning disable 0649
[SerializeField] protected CanvasGroup canvasGroup; // TODO ¤¢¤È¤Ç TextViewBase ¤È ViewBase ¤È¤·¤Æ¶¦Ä̲½¤¹¤ë
[SerializeField] protected Canvas canvas; // ¤¢¤È¤Ç TextViewBase ¤È¶¦Ä̲½¤¹¤ë
[SerializeField] protected Slider slider;
#pragma warning restore 0649
/// <summary>
/// ¥¹¥é¥¤¥À¡¼É½¼¨¹¹¿·
/// </summary>
/// <param name="currentValue"></param>
public virtual void UpdateBar(float currentValue) {
slider.DOValue(currentValue, 0.1f).SetEase(Ease.Linear).SetLink(gameObject);
}
/// <summary>
/// ½é´üÀßÄê
/// </summary>
/// <param name="maxValue"></param>
public virtual void SetUpView(float maxValue) {
slider.maxValue = maxValue;
if (canvas.worldCamera == null) {
canvas.worldCamera = Camera.main;
}
}
/// <summary>
/// ¥¹¥é¥¤¥À¡¼É½¼¨
/// </summary>
public virtual void ShowBarView() {
//canvasGroupTextView.alpha = 1.0f;
canvas.enabled = true;
}
/// <summary>
/// ¥¹¥é¥¤¥À¡¼Èóɽ¼¨
/// </summary>
public virtual void HideBarView() {
//canvasGroupTextView.alpha = 0f;
canvas.enabled = false;
}
public Transform GetCanvasTran() {
return canvas.transform;
}
}
using UniRx;
/// <summary>
/// ¹¶·â½èÍý Model
/// </summary>
public class AttackModeModel {
public ReactiveProperty<float> CurrentActionGaugePoint;
private readonly CompositeDisposable disposables = new();
public float MaxActionGaugePoint { get; private set; }
public float AttackSpeed { get; private set; }
public int Atk { get; private set; }
public int Inte { get; private set; }
public int Def { get; private set; }
public int Mdef { get; private set; }
public float AttackRange { get; private set; }
public DamageType DamageType { get; private set; }
public eAttribute AttributeType { get; private set; }
public int MinDmg { get; private set; }
public AttackModeModel(float attackSpeed, int atk, float attackRange) { }
/// <summary>
/// ¥³¥ó¥¹¥È¥é¥¯¥¿
/// </summary>
/// <param name="maxAttackPoint">ConstData ¤«¤é»²¾È(300)</param>
/// <param name="spd">ConstaData ¤«¤é»²¾È(199) + spd</param>
/// <param name="atk"></param>
/// <param name="inte"></param>
/// <param name="def"></param>
/// <param name="mdef"></param>
/// <param name="attackRange">¹¶·âÈϰÏ</param>
/// <param name="damageType">¹¶·â¤Î¥¿¥¤¥×¡£ÊªÍý¤«ËâË¡</param>
/// <param name="attributeType">¹¶·â¤Î°À</param>
/// <param name="minDmg">ºÇ¾®¥À¥á¡¼¥¸ÃÍPlayer = 0</param>
public AttackModeModel(float spd, int atk, int inte, int def, int mdef, float attackRange, DamageType damageType, eAttribute attributeType, int minDmg = 0) {
CurrentActionGaugePoint = new(0f);
MaxActionGaugePoint = ConstData.MAX_ACTION_GAUGE_POINT;
AttackSpeed = ConstData.ATTACK_SPEED_OFFSET + spd;
Atk = atk;
Inte = inte;
Def = def;
Mdef = mdef;
AttackRange = attackRange;
DamageType = damageType;
AttributeType = attributeType;
MinDmg = minDmg;
}
/// <summary>
/// ¥¢¥¯¥·¥ç¥ó¥²¡¼¥¸ÃͤΥꥻ¥Ã¥È
/// </summary>
public void ResetActionGaugePoint() {
CurrentActionGaugePoint.Value = 0f;
}
/// <summary>
/// ¥ª¥Ö¥¸¥§¥¯¥È(¥¤¥ó¥¹¥¿¥ó¥¹)¤¬ÇË´þ¤µ¤ì¤ë¤È¤¤ËCompositeDisposable¤ÎDispose¤â¸Æ¤Ó½Ð¤¹
/// </summary>
public void Dispose() {
// Dispose ¥á¥½¥Ã¥É¤¬¸Æ¤Ð¤ì¤¿¤È¤¤Ë¡¢CompositeDisposable ¤Ë´Þ¤Þ¤ì¤ëÁ´¤Æ¤Î¥¹¥È¥ê¡¼¥à¤¬¼«Æ°Åª¤Ë²òÊü
disposables.Dispose();
}
}
/// <summary>
/// ¹¶·â½èÍý View
/// </summary>
public class ActionGuageBar : BarBase {
/// <summary>
/// ½é´üÀßÄê
/// </summary>
/// <param name="maxValue"></param>
public override void SetUpView(float maxValue) {
base.SetUpView(maxValue);
// ½é´üÃͤò 0 ¤ËÀßÄê
slider.value = 0;
// ±£¤¹
HideBarView();
}
/// <summary>
/// ¹¶·â¥²¡¼¥¸¤Îɽ¼¨¹¹¿·
/// </summary>
/// <param name="currentValue"></param>
public override void UpdateBar(float currentValue) {
slider.value = currentValue;
}
}
using UnityEngine;
using UniRx;
using UniRx.Triggers;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// ¹¶·â½èÍý Presenter
/// </summary>
public class AttackModePresenter : ISetup {
private LifeBase attackTarget;
private ReactiveProperty<bool> IsAttackReady = new(false);
private AttackModeModel myAttackModeModel;
private ActionGuageBar attackModeView;
private HpBar hpBarView;
private AttackRangeCollider attackRangeCollider;
/// <summary>
/// ¥³¥ó¥¹¥È¥é¥¯¥¿
/// </summary>
public AttackModePresenter() {}
/// <summary>
/// ¥³¥ó¥¹¥È¥é¥¯¥¿
/// </summary>
/// <param name="spd"></param>
/// <param name="attackPower"></param>
/// <param name="attackRange"></param>
public AttackModePresenter(float spd, int atk, int inte, int def, int mdef, float attackRange, DamageType damageType, eAttribute attributeType, int minDmg = 0) {
myAttackModeModel = new(spd, atk, inte, def, mdef, attackRange, damageType, attributeType, minDmg);
}
/// <summary>
/// ½é´üÀßÄê
/// </summary>
/// <param name="entityObject"></param>
public void SetUp(GameObject entityObject) {
// entityObject ¤«¤é¹¶·âÍѤΥǡ¼¥¿¤ò»²¾È¤·¤Æ¤â¤é¤¦
if (entityObject.TryGetComponent(out attackModeView)) {
attackModeView.SetUpView(ConstData.MAX_ACTION_GAUGE_POINT);
}
// Hp ¼èÆÀ
LifeBase myLife;
if (!entityObject.TryGetComponent(out myLife)) {
return;
}
myAttackModeModel = myLife.AttackModeModel;
// HpBar ¼èÆÀ
if (entityObject.TryGetComponent(out hpBarView)) {
hpBarView.SetUpView(myLife.Hp.Value);
}
// Hp ¤Î¹ØÆÉ Hp ¥²¡¼¥¸¹¹¿·
myLife.Hp.Subscribe(hp => hpBarView.UpdateBar(myLife.Hp.Value)).AddTo(entityObject);
// ¹¶·âÈϰÏÍѤΥ³¥é¥¤¥À¡¼¤Î¼èÆÀ¤¬¤Ç¤¤Ê¤¤¾ì¹ç¡¢½èÍý¤·¤Ê¤¤
if (!entityObject.TryGetComponent(out attackRangeCollider)) {
return;
}
// ¹¶·âÈϰϤΥ³¥é¥¤¥À¡¼¤Î¥µ¥¤¥º¤òÀßÄê
attackRangeCollider.SetUpColliderRange(myAttackModeModel.AttackRange);
// ¥â¥Ã¥¯ÍÑ
if (myLife.EntityType == EntityType.Enemy) {
return;
}
// ¹¶·âÂоݤȤʤ륿¥°¤òÀßÄê
string tag = myLife.GetTargetEntityType().ToString();
// ¹¶·âÂоݤÎõº÷
entityObject.UpdateAsObservable()
.Subscribe(_ => SearchAttackTarget(entityObject, tag));
// ¿¯ÆþȽÄê¤Î¹ØÆÉ ¼«Æ°¹¶·â½àÈ÷
//attackRangeCollider.AttackRange.OnTriggerStay2DAsObservable()
// .Where(col => attackTarget == null)
// .Where(col => col.transform.TryGetComponent(out attackTarget)) // ¥³¥é¥¤¥À¡¼¤Ø¤Î¿¯ÆþȽÄê
// .Where(_ => myLife.CheckTarget(attackTarget.EntityType)) // ¹¶·âÂоݤ«È½Äê
// .Subscribe(col => {
// // ¹¶·â½àÈ÷³«»Ï¤È¥²¡¼¥¸É½¼¨
// IsAttackReady.Value = true;
// attackModeView.ShowBarView();
// Debug.Log($"¹¶·â½àÈ÷ ³«»Ï {attackTarget}");
// });
// ¤¤¤Ê¤¯¤Ê¤Ã¤¿È½Äê¤Î¹ØÆÉ ¼«Æ°¹¶·âÄä»ß
//attackRangeCollider.AttackRange.OnTriggerExit2DAsObservable()
// .Where(col => col.transform.TryGetComponent(out attackTarget)) // ¥³¥é¥¤¥À¡¼¤Ø¤Î¿¯ÆþȽÄê
// .Where(_ => myLife.CheckTarget(attackTarget.EntityType)) // ¹¶·âÂоݤ«È½Äê
// .Subscribe(col => StopAttack());
// Update ¤Î¹ØÆÉ
entityObject.UpdateAsObservable()
.Where(_ => IsAttackReady.Value)
.Where(_ => myAttackModeModel.CurrentActionGaugePoint.Value < myAttackModeModel.MaxActionGaugePoint)
.Subscribe(_ => {
// ¹¶·â¥²¡¼¥¸¤Î²Ã»»
myAttackModeModel.CurrentActionGaugePoint.Value += myAttackModeModel.AttackSpeed * Time.deltaTime;
// ¹¶·â¥²¡¼¥¸¤Î View ¹¹¿·
attackModeView.UpdateBar(myAttackModeModel.CurrentActionGaugePoint.Value);
});
// ¹¶·â¥²¡¼¥¸¤Î¹ØÆÉ
myAttackModeModel.CurrentActionGaugePoint
.Where(_ => attackTarget)
.Where(currentActionGaugePoint => currentActionGaugePoint >= myAttackModeModel.MaxActionGaugePoint)
.Subscribe(_ => {
if (attackTarget == null) {
// ¥¢¥¯¥·¥ç¥ó¥²¡¼¥¸¥ê¥»¥Ã¥È
myAttackModeModel.ResetActionGaugePoint();
} else {
// ¼«Æ°¹¶·â
AutoAttack();
}
})
.AddTo(entityObject);
// Ç˲õ»þ¤Î¹ØÆÉ
entityObject.OnDestroyAsObservable().Subscribe(_ => myAttackModeModel.Dispose());
// TODO ̾Á°É½¼¨
//Debug.Log($"{this} Setup ´°Î»");
}
/// <summary>
/// ¼«Æ°¹¶·â
/// </summary>
private void AutoAttack() {
//Debug.Log("¼«Æ°¹¶·â");
// °À·¸¿ô»»½Ð
float attributeRate = BattleCalculater.CalcAttributeRate(myAttackModeModel.AttributeType, attackTarget.AttackModeModel.AttributeType);
//Debug.Log($"°ÀÊäÀµ : {attributeRate}");
//Debug.Log($"¹¶·âÎÏ : {myAttackModeModel.Atk}");
//Debug.Log($"ÃÎÎÏ : {myAttackModeModel.Inte}");
//Debug.Log($"ËɸæÎÏ : {attackTarget.AttackModeModel.Def}");
// ¸½ºß¤Î¹¶·â¥¿¥¤¥×¤ò¸µ¤Ë¥À¥á¡¼¥¸·×»»
int damage = myAttackModeModel.DamageType == DamageType.atk
? BattleCalculater.CalcAtkDamage(myAttackModeModel.Atk, myAttackModeModel.Inte, attributeRate, attackTarget.AttackModeModel.Def) // ʪÍý¥À¥á¡¼¥¸
: BattleCalculater.CalcInteDamage(myAttackModeModel.Inte, myAttackModeModel.Atk, attributeRate, attackTarget.AttackModeModel.Mdef); // ËâË¡¥À¥á¡¼¥¸
Debug.Log($"ºÇ½ª¥À¥á¡¼¥¸ : {damage}");
// ¥¢¥¯¥·¥ç¥ó¥²¡¼¥¸¥ê¥»¥Ã¥È
myAttackModeModel.ResetActionGaugePoint();
// ¹¶·âÂоݤ¬»Ä¤Ã¤Æ¤¤¤ë¤«³Îǧ
if (attackTarget == null) {
Debug.Log("¹¶·âÂоݾüº");
return;
}
// ¥À¥á¡¼¥¸Ãͤò¥Õ¥í¡¼¥Èɽ¼¨¡£¥ª¥Ö¥¸¥§¥¯¥È¥×¡¼¥ëÍøÍÑ
attackTarget.ShowFloatingView(damage);
//FloatingView floatingView = (FloatingView)FloatingViewGenerator.instance.GetObjectFromPool(attackTarget.transform.position, attackTarget.transform.rotation);
//floatingView.SetUpView(damage.ToString());
// Hp ·×»»¡£ÂоݤΠ»Ä hp ¤¬ 0 °Ê²¼¤Ê¤é
if (!attackTarget.CalcLife(-damage)) {
// ¼«Æ°¹¶·âÄä»ß
StopAttack();
}
//Debug.Log("¹¶·â´°Î»");
}
/// <summary>
/// ¼«Æ°¹¶·âÄä»ß
/// </summary>
private void StopAttack() {
attackTarget = null;
// ¹¶·âÄä»ß¡£¥¢¥¯¥·¥ç¥ó¥²¡¼¥¸¥ê¥»¥Ã¥È¤È¥²¡¼¥¸Èóɽ¼¨
IsAttackReady.Value = false;
myAttackModeModel.ResetActionGaugePoint();
attackModeView.HideBarView();
//Debug.Log("¹¶·âÄä»ß");
}
/// <summary>
/// ¹¶·âÎϤʤɤΥǡ¼¥¿¹¹¿·
/// </summary>
/// <param name="attackModeModel"></param>
public void UpdateAttackModel(AttackModeModel attackModeModel, GameObject entityObject) {
myAttackModeModel = attackModeModel;
myAttackModeModel.Dispose();
// ¹¶·â¥²¡¼¥¸¤Î¹ØÆÉ¤ä¤êľ¤·
myAttackModeModel.CurrentActionGaugePoint
.Where(_ => attackTarget)
.Where(currentActionGaugePoint => currentActionGaugePoint >= myAttackModeModel.MaxActionGaugePoint)
.Subscribe(_ => AutoAttack())
.AddTo(entityObject);
Debug.Log("¹¹¿·");
}
/// <summary>
/// ¹¶·âÂоݤÎõº÷
/// </summary>
/// <param name="entityObject"></param>
/// <param name="tag"></param>
private void SearchAttackTarget(GameObject entityObject, string tag) {
// OverlapCircleAll ¥á¥½¥Ã¥É¤òÍøÍѤ·¤Æ¡¢ÈÏ°ÏÆâ¤Î¥³¥é¥¤¥À¡¼ÉÕ¤¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò¼èÆÀ
//Collider2D[] hitColliders = Physics2D.OverlapCircleAll(entityObject.transform.position, myAttackModeModel.AttackRange / 2);
//List<GameObject> objList = new();
//// ÇÛÎóÆâ¤ÎÍ×ÁǤò£±¤Ä¤º¤Ä¼è¤ê½Ð¤¹
//foreach (Collider2D collider in hitColliders) {
// // »ØÄꤵ¤ì¤¿¥¿¥°¤ò»ý¤Ä¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¤«È½Äê¡£¤½¤ì¤ò¹¶·âÂоݸõÊä¤È¤·¤ÆÇ§¼±
// if (collider.gameObject.CompareTag(tag)) {
// objList.Add(collider.gameObject);
// }
//}
// ¾åµ¤ò LINQ ¤Çµ½Ò
List<GameObject> objList = Physics2D.OverlapCircleAll(entityObject.transform.position, myAttackModeModel.AttackRange / 2)
.Where(collider => collider.CompareTag(tag))
.Select(collider => collider.gameObject)
.ToList();
// ¼èÆÀ¤·¤¿¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤¬ 0 ¤Ê¤é¹¶·âÂоݤθõÊä¤Ê¤·
if (objList.Count == 0) {
Debug.Log("¹¶·âÂоݤʤ·");
StopAttack();
return;
}
// ºÇ¤â¶á¤¤¥ª¥Ö¥¸¥§¥¯¥È¤Îµ÷Î¥¤òÂåÆþ¤¹¤ë¤¿¤á¤ÎÊÑ¿ô
//float nearDistance = 0;
// ¸¡º÷¤µ¤ì¤¿ºÇ¤â¶á¤¤¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤òÂåÆþ¤¹¤ë¤¿¤á¤ÎÊÑ¿ô
//GameObject searchTargetObj = null;
// objs¤«¤é£±¤Ä¤º¤ÄobjÊÑ¿ô¤Ë¼è¤ê½Ð¤¹
//foreach (GameObject obj in objList) {
// // obj¤Ë¼è¤ê½Ð¤·¤¿¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤È¡¢¤³¤Î¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤È¤Îµ÷Î¥¤ò·×»»¤·¤Æ¼èÆÀ
// float distance = Vector3.Distance(obj.transform.position, entityObject.transform.transform.position);
// // nearDistance¤¬0(ºÇ½é¤Ï¤³¤Á¤é)¡¢¤¢¤ë¤¤¤ÏnearDistance¤¬distance¤è¤ê¤âÂ礤¤Ãͤʤé
// if (nearDistance == 0 || nearDistance > distance) {
// // nearDistance¤ò¹¹¿·
// nearDistance = distance;
// // searchTargetObj¤ò¹¹¿·
// searchTargetObj = obj;
// }
//}
// ¾åµ¤ò LINQ ¤Çµ½Ò¡£ºÇ¤â¶á¤¤ÂоݤòÃê½Ð
GameObject searchTargetObj = objList
.OrderBy(obj => Vector3.Distance(obj.transform.position, entityObject.transform.position))
.FirstOrDefault();
//ºÇ¤â¶á¤«¤Ã¤¿¥ª¥Ö¥¸¥§¥¯¥È¤ò¹¶·âÂоݤȤ¹¤ë
attackTarget = searchTargetObj.GetComponent<LifeBase>();
// ¹¶·â½àÈ÷³«»Ï¤È¥²¡¼¥¸É½¼¨
IsAttackReady.Value = true;
attackModeView.ShowBarView();
Debug.Log($"¹¶·â½àÈ÷ ³«»Ï {attackTarget}");
}
}
¡¡»ØÄꤷ¤¿ÈÏ°ÏÆâ¤Ë¥³¥é¥¤¥À¡¼¤òŸ³«¤·¡¢¤½¤ÎÈÏ°ÏÆâ¤Ë¤¢¤ë¥³¥é¥¤¥À¡¼¤ò¼èÆÀ¤·¤ÆÇÛÎó¤ËÂåÆþ¤¹¤ë¥á¥½¥Ã¥É¤Ç¤¹¡£
¡¡¥ì¥¤¥ä¡¼¤Ç»ØÄꤷ¡¢GC ¤ò¾¯¤Ê¤¯¤¹¤ë OverlapCircleNonAlloc ¥á¥½¥Ã¥É¤â¤¢¤ê¤Þ¤¹¡£
https://docs.unity3d.com/ja/current/ScriptReferenc...
https://docs.unity3d.com/ja/current/ScriptReferenc...
- ¥«¥Æ¥´¥ê¡§
- ¿Ê³Ø/¥¹¥¯¡¼¥ë
- ¥×¥í¥°¥é¥ß¥ó¥°




¤³¤Î¥Ú¡¼¥¸¤Ø¤Î¥³¥á¥ó¥È
UniRX¤ò»È¤¦¤È¤É¤ó¤Ê¤È¤³¤í¤¬¤¤¤¤¤Ç¤¹¤«¡©
»ä¤Ï´Ú¹ñ¿Í¤Ç¡¢¸½ºß2D Action RPG¤òºî¤Ã¤Æ¤¤¤Þ¤¹¡£
¾ðÊó¤òõ¤·¤Æ¤¤¤ëÅÓÃæ¡¢»ä¤¬Ë¾¤à¾ðÊó¤È»÷¤¿¾ðÊó¤ò¸«¤Ä¤±¤¿¤è¤¦¤Ê¤Î¤Ç¡¢¤ªÊ¹¤¤·¤¿¤¤¤Î¤Ç¤¹¤¬¡¢UniRX¤Ë¤Ï¤É¤Î¤è¤¦¤Ê¥á¥ê¥Ã¥È¤¬¤¢¤ë¤Î¤Ç¤·¤ç¤¦¤«¡©
ÉÔËܰդʤ¬¤é¤ª¼ê¿ô¤ò¤ª¤«¤±¤·¤Æ¿½¤·Ìõ¤¢¤ê¤Þ¤»¤ó¡£
UniRx ¤Ë¤Ï¿¤¯¤Î¥á¥ê¥Ã¥È¤¬¤¢¤ê¤Þ¤¹¤¬¡¢ºÇ¤âͱפǡ¢»È¤¤¤ä¤¹¤¤Éôʬ¤È¤·¤Æ¤Ï¡¢°ìÏ¢¤Î½èÍý¤ò¥¤¥Ù¥ó¥È²½¤·¤Æ¤¯¤ì¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
¤³¤ì¤Ï¡¢¥Ü¥¿¥ó¤ò²¡¤¹¤È¥á¥½¥Ã¥É¤¬¼Â¹Ô¤µ¤ì¤ë¡¢¤È¤¤¤¦¥¤¥Ù¥ó¥È¤ò¡¢¤Û¤«¤Î½èÍý¤Ë¤â±þÍѤǤ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
Î㤨¤Ð¡¢int ·¿¤ÎÊÑ¿ô¤¬¤¢¤ë¤È¤·¡¢¤³¤ì¤Ï¥¹¥³¥¢¤ò´ÉÍý¤·¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£¥¹¥³¥¢¤ÏÆâÉôŪ¤Ë²Ã»»¤¹¤ë¤À¤±¤Ç¤Ï¤Ê¤¯¡¢¥²¡¼¥à²èÌ̤ˤâɽ¼¨¹¹¿·¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
UniRx ¤òÍøÍѤ¹¤ë¤³¤È¤Ç¡Ö¥¹¥³¥¢¤¬²Ã»»¤µ¤ì¤¿¤é¡¢²èÌ̤Υ¹¥³¥¢É½¼¨¤ò¹¹¿·¤¹¤ë¡×¤È¤¤¤¦¥¤¥Ù¥ó¥È¤òºî¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£
¤³¤Î¤è¤¦¤Ê¥¤¥Ù¥ó¥È¤òºî¤Ã¤Æ¤ª¤¯¤³¤È¤Ç¡¢»ä¤¿¤Á¤Ï¥¹¥³¥¢¤ò²Ã»»¤¹¤ë½èÍý¤ò½ñ¤¯¤À¤±¤Ç¡¢¼«Æ°Åª¤Ë²èÌ̤Îɽ¼¨¤¬¹¹¿·¤µ¤ì¤ë¤è¤¦¤Ë¤Ç¤¤Þ¤¹¡£
¤³¤ì¤Ï UniRx ¤ËÍѰդµ¤ì¤Æ¤¤¤ë ReactiveProperty ¤È¤¤¤¦µ¡Ç½¤ò»È¤¦¤³¤È¤Ç´Êñ¤Ë¼ÂÁõ¤Ç¤¤Þ¤¹¡£
¤Þ¤º¤Ï¤³¤Îµ¡Ç½¤ò»È¤Ã¤Æ¤ß¤Æ¡¢¥¤¥Ù¥ó¥È¤òºî¤ë¤È¤Ï¤É¤¦¤¤¤¦¤³¤È¤Ê¤Î¤«¤ò¡¢Â賤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
´·¤ì¤Æ¤¯¤ì¤Ð¡¢¡Ö(¥²¡¼¥àÆâÉôŪ¤Ë)ÁõÈ÷¤òÊѹ¹¤·¤¿¤é¡¢²èÌ̾å¤Î¥¢¥¤¥³¥ó¤äÁõÈ÷¥â¥Ç¥ë¤¬¼«Æ°Åª¤ËÀÚ¤êÂØ¤ï¤ë¡×¤È¤¤¤Ã¤¿µ¡Ç½¤òºî¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡£
¤Þ¤¿¡¢¤½¤Î¤¿¤á¤Ë¤Ï¡¢¥Ç¥¶¥¤¥ó¥Ñ¥¿¡¼¥ó¤È¸Æ¤Ð¤ì¤ë¡¢¥×¥í¥°¥é¥à¤ÎÄêÀФòÍý²ò¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
UniRx ¤Ï¥ª¥Ö¥¶¡¼¥Ð¡¼¥Ñ¥¿¡¼¥ó¤È¸Æ¤Ð¤ì¤ë¤â¤Î¤Ë¤è¤Ã¤Æºî¤é¤ì¤Æ¤¤¤Þ¤¹¡£
¤Þ¤¿¡¢UniRx ¤Î½èÍý¤Ï¥á¥½¥Ã¥É¡¦¥Á¥§¡¼¥ó¤ò»È¤Ã¤Æ¤«¤«¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï LINQ ¤ä DOTween ¤Ç¤â»È¤ï¤ì¤Æ¤¤¤ë¡¢Ê£¿ô¤Î¥á¥½¥Ã¥É¤ò³¤±¤Æ½ñ¤¤¤Æ¤¤¤¯µ¡Ç½¤Ç¤¹¡£
LINQ ¤Ï¥Ç¥ê¥²¡¼¥È¤Îµ¡Ç½¤òÍý²ò¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£
¤½¤Î¤¿¤á¡¢UniRx ¤Î³Ø½¬¤ò¹Ô¤¦Á°Äó¤È¤·¤Æ¡¢¥Ç¥ê¥²¡¼¥È¤Îµ¡Ç½¤òÍý²ò¤·¡¢¥ª¥Ö¥¶¡¼¥Ð¡¼¥Ñ¥¿¡¼¥ó¤òÍý²ò¤·¤Æ¤¤¤¯¤È¤è¤¤¤Ç¤·¤ç¤¦¡£
¤Þ¤¿½èÍý¤ÎÃê¾Ý²½¤È¤¤¤¦¹Í¤¨Êý¤âɬÍפˤʤäƤ¤Þ¤¹¤Î¤Ç¡¢¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤äÃê¾Ý¥¯¥é¥¹(¥¯¥é¥¹¤Î·Ñ¾µ¡¢¥Ý¥ê¥â¡¼¥Õ¥£¥º¥à)¤È¤¤¤Ã¤¿¡¢¥×¥í¥°¥é¥à¤Î³Ø½¬¤â¤·¤Æ¤ª¤¯¤È¤è¤¤¤Ç¤¹¡£
±þ±ç¤·¤Æ¤¤¤Þ¤¹¡£
¤¬¤ó¤Ð¤Ã¤Æ¤¯¤À¤µ¤¤¡£