/// <summary> /// アイテムを投げるアクション /// </summary> public IObservable <Unit> ThrowAnimation(CharacterThrowAction action) { var dis = action.TargetPosition - action.Character.Position; var basePosition = this.Presenter.transform.localPosition; var noGameObject = action.TargetItem.Presenter == null; var frame = Mathf.Max(Mathf.Abs(dis.x), Mathf.Abs(dis.y)) * 3 + 2; var throwAction = Observable.Defer(() => { if (noGameObject) { //オブジェクトがない場合は表示用に生成 action.TargetItem.InstantiateObject(dungeon.DungeonPrefabs.ObjectPrefab, dungeon.ObjectRoot); } action.TargetItem.Presenter.transform.localPosition = basePosition; return(Observable.EveryUpdate()); }) .Take(frame) .Do(i => { // アイテムが飛んでくアニメーション action.TargetItem.Presenter.transform.localPosition = basePosition + new Vector3(dis.x * DungeonConstants.MAPTIP_PIXCEL_SIZE * i / frame, -dis.y * DungeonConstants.MAPTIP_PIXCEL_SIZE * i / frame); }) .Last() .Do(_ => { if (noGameObject) { //表示用に作ったやつの後片付け GameObject.Destroy(action.TargetItem.Presenter.gameObject); } else { //オブジェクトがあるのは床落ちなので表示位置リセットして終了 action.TargetItem.ResetViewPotition(); } }) .AsUnitObservable(); var damageAnimation = action.SubActions .Where(x => x as CharacterDamagedAction != null) .Select(x => DamageAnimation(x as CharacterDamagedAction)) .Concat(); var otherAnimation = ActionAnimations(action.SubActions.Where(x => x as CharacterDamagedAction == null).ToArray()); return(throwAction.Concat(damageAnimation).Last() .SelectMany(otherAnimation).Last()); }
public bool ThrowItemCore(Item item) { //矢弾の場合は1つずつ処理するので1個のオブジェクトを新たに生成 if (item.Category == ItemCategory.Arrow && item.CountValue > 1) { item = new Item(dungeon, item.MasterId, 1); } var targetPosition = this.Position; var range = 10;//飛距離 var subActions = new List <CharacterAction>(); for (int i = 1; i <= range; i++) { targetPosition += this.Direction; //画面外 if (targetPosition.x < 0 || targetPosition.x >= dungeon.MapSize.x || targetPosition.y < 0 || targetPosition.y >= dungeon.MapSize.y) { Debug.LogFormat("{0}は彼方へと飛んでいった…", item.Name); break; } //壁 if (dungeon.MapData[targetPosition.x, targetPosition.y].Terra == Enums.Terrain.Wall) { targetPosition -= this.Direction; item.DropFloor(targetPosition); break; } //他のキャラ var target = dungeon.Characters.Where(x => !x.IsDeath).FirstOrDefault(x => x.Position == targetPosition); if (target != null) { //命中判定 var isHit = (int)UnityEngine.Random.Range(0, 100) >= Mathf.Clamp(target.Params.Agi - this.Params.Dex + 20, 0, 95); if (isHit) { // 命中処理(targetのアイテムをぶつけられた処理呼び出し) subActions.AddRange(target.HitItem(item, this)); Debug.LogFormat("{0}は{1}に命中した", item.Name, target.Name); //相手死亡判定 if (target.IsDeath) { subActions.AddRange(KillCharacter(target)); } } else { item.DropFloor(targetPosition); } break; } //何もぶつからずに飛距離終わり if (i == range) { item.DropFloor(targetPosition); } } var action = new CharacterThrowAction(this, item, targetPosition); action.SubActions.AddRange(subActions); this.ReservedActions.Add(action); return(true); }