private void PlaceBlock(Ray ray, IWorld world) { if (Input.GetMouseButtonDown(1)) { BlockData block = world.BlockDataTable.GetBlock(m_HandBlockInput.text); if (Physics.RaycastBlock(ray, RaycastMaxDistance, world, m_PlaceRaycastSelector, out BlockRaycastHit hit)) { Vector3Int pos = (hit.Position + hit.Normal).FloorToInt(); AABB playerBB = m_PlayerEntity.BoundingBox + m_PlayerEntity.Position; AABB blockBB = hit.Block.GetBoundingBox(pos, world, false).Value; if (!playerBB.Intersects(blockBB)) { Quaternion rotation = Quaternion.identity; // !!! 一定要按下面的顺序相乘,才能保证先绕 y 再绕 xz if ((block.RotationAxes & BlockRotationAxes.AroundXOrZAxis) == BlockRotationAxes.AroundXOrZAxis) { rotation *= Quaternion.FromToRotation(Vector3.up, hit.Normal); // 底部朝向法线 } if ((block.RotationAxes & BlockRotationAxes.AroundYAxis) == BlockRotationAxes.AroundYAxis) { Vector3 forward = m_PlayerEntity.Forward; forward = Mathf.Abs(forward.x) > Mathf.Abs(forward.z) ? new Vector3(forward.x, 0, 0) : new Vector3(0, 0, forward.z); rotation *= Quaternion.LookRotation(-forward.normalized, Vector3.up); // 看向玩家 } world.RWAccessor.SetBlock(pos.x, pos.y, pos.z, block, rotation, ModificationSource.PlayerAction); } } } }
private void DigBlock(Ray ray, IWorld world) { if (Physics.RaycastBlock(ray, RaycastMaxDistance, world, m_DestroyRaycastSelector, out BlockRaycastHit hit)) { ShaderUtility.TargetedBlockPosition = hit.Position; if (Input.GetMouseButton(0)) { if (m_IsDigging) { if (hit.Position == m_FirstDigPos) { m_DiggingDamage += Time.deltaTime * 5; SetDigProgress(m_DiggingDamage / hit.Block.Hardness); if (m_DiggingDamage >= hit.Block.Hardness) { SetDigProgress(0); m_IsDigging = false; world.RWAccessor.SetBlock(hit.Position.x, hit.Position.y, hit.Position.z, world.BlockDataTable.GetBlock(0), Quaternion.identity, ModificationSource.PlayerAction); //block.PlayDigAudio(m_AudioSource); // if (Setting.SettingManager.Active.RenderingSetting.EnableDestroyEffect) // { // ParticleSystem effect = Instantiate(m_DestroyEffectPrefab, firstHitPos + new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity).GetComponent<ParticleSystem>(); // ParticleSystem.MainModule main = effect.main; // main.startColor = block.DestoryEffectColor; // } } } else { SetDigProgress(0); m_IsDigging = false; } } else { BlockData block = world.RWAccessor.GetBlock(hit.Position.x, hit.Position.y, hit.Position.z); m_IsDigging = true; m_DiggingDamage = 0; m_FirstDigPos = hit.Position; } } if (Input.GetMouseButtonDown(0)) { m_ClickedPos = hit.Position; m_ClickTime = Time.time; } if (Input.GetMouseButtonUp(0)) { SetDigProgress(0); m_IsDigging = false; BlockData block = world.RWAccessor.GetBlock(hit.Position.x, hit.Position.y, hit.Position.z); if ((hit.Position == m_ClickedPos) && (Time.time - m_ClickTime <= MaxClickSpacing)) { block.Click(world, hit.Position.x, hit.Position.y, hit.Position.z); } m_ClickedPos = Vector3Int.down; m_ClickTime = 0; } } else { // 无选定方块 ShaderUtility.TargetedBlockPosition = Vector3.down; } }