進めていくと、どんどんわからないことが複雑になりますね。
システムのバグなのか、こちらのミスなのかの見分けは過去ログを見るしかないです。
後、質問サイト投稿への返信が日曜日なのに、数時間後なのが地味にすごいと感心しています。
最近はyahoo知恵袋を愛用しています。
//tips
//Particleを用いた衝突反応
Particleのインスペクターのcollisionにチェック、さらに、小項目のcollision typeをworldに、send collision messagesにもチェックを入れる。
これでParticleに対してcolliderが設置できたのでスクリプトに衝突反応を記載していく必要がある。
UnityでOnParticleCollisionメソッドを確認するために、ParticleとCubeを作成し、Cubeに下記のスクリプトを貼り付けたところ大量のエラーが発生。
```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Part : MonoBehaviour
{
private void OnParticleCollision(GameObject other)
{
Debug.Log("hit!");
}
}
```
まずCubeオブジェクトにスクリプトがアタッチできず、
「can't add script」の表示が出てエラーを確認するとUnityに最初から入っているスクリプトに反応しているようなので、該当箇所を消してあげるのですが、次から次へとエラー箇所が出てきて対処が難しく感じ質問中。
Assets/SampleScenes/Scripts/ParticleSceneControls.cs(132,57): error CS0246: The type or namespace name 'ParticleSystemMultiplier' could not be found (are you missing a using directive or an assembly reference?)
Assets/SampleScenes/Scripts/ParticleSceneControls.cs(205,70): error CS0246: The type or namespace name 'ParticleSystemMultiplier' could not be found (are you missing a using directive or an assembly reference?)
下記参考。
https://www.youtube.com/results?search_query=unity+onparticlecollision
https://docs.unity3d.com/ja/current/ScriptReference/MonoBehaviour.OnParticleCollision.html
https://qiita.com/Mikoshi/items/ed2e02acdce3ee5c3998
https://gametukurikata.com/effect/particlecollision
https://qrunch.net/@horukasu/entries/4XkZ79RisAae5be2
//Unityの名前空間
名前空間とはスクリプトの最上部に記載されるusingから始まるもので、usingの後に記載された文言のことを指すフォルダのようなもの。
このフォルダごとにUnityで使用されるプログラムの機能を集約している。
さらに、using System.Collections.Generic;のように「.」が連続しているものは、Systemフォルダの中のCollectionsフォルダの中のGenericフォルダに入っている機能を使うということになる。
名前空間を自分で定義すると、
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FolderA
{
namespace FolderB
{
public class A : MonoBehavior
{
void Start()
{}
}
}
}
となり、これをusingを使用して呼び出すと
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FolderA.FolderB
public class B : MonoBehavior
{
void Start()
{
A a = GetComponent<A>();
}
のように使用することができる。
この名前空間フォルダの中にはclassや構造体を入れることができ、さらにその下にフィールドやメソッドが追加されていくことになる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
public class A
{
int a; //フィールド
void B() //メソッド
{}
class C //内部クラス
{}
struct D//入れご型
{}
public struct B
{}
}
}
エラーの要因はUnityのバックグラウンド(名前空間)に組み込まれているParticleSceneControllerプログラムがうまく作動していないため修正する必要があるとのこと。
下記がParticleSceneControllerプログラムの内容となる。
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityStandardAssets.Effects;
namespace UnityStandardAssets.SceneUtils
{
public class ParticleSceneControls : MonoBehaviour
{
public enum Mode
{
Activate,
Instantiate,
Trail
}
public enum AlignMode
{
Normal,
Up
}
public DemoParticleSystemList demoParticles;
public float spawnOffset = 0.5f;
public float multiply = 1;
public bool clearOnChange = false;
public Text titleText;
public Transform sceneCamera;
public Text instructionText;
public Button previousButton;
public Button nextButton;
public GraphicRaycaster graphicRaycaster;
public EventSystem eventSystem;
private List<Transform> m_CurrentParticleList = new List<Transform>();
private Transform m_Instance;
private static int s_SelectedIndex = 0;
private Vector3 m_CamOffsetVelocity = Vector3.zero;
private Vector3 m_LastPos;
private static DemoParticleSystem s_Selected;
private object m_ParticleMultiplier;
private void Awake()
{
Select(s_SelectedIndex);
previousButton.onClick.AddListener(Previous);
nextButton.onClick.AddListener(Next);
}
private void OnDisable()
{
previousButton.onClick.RemoveListener (Previous);
nextButton.onClick.RemoveListener (Next);
}
private void Previous()
{
s_SelectedIndex--;
if (s_SelectedIndex == -1)
{
s_SelectedIndex = demoParticles.items.Length - 1;
}
Select(s_SelectedIndex);
}
public void Next()
{
s_SelectedIndex++;
if (s_SelectedIndex == demoParticles.items.Length)
{
s_SelectedIndex = 0;
}
Select(s_SelectedIndex);
}
private void Update()
{
#if !MOBILE_INPUT
KeyboardInput();
#endif
sceneCamera.localPosition = Vector3.SmoothDamp(sceneCamera.localPosition, Vector3.forward*-s_Selected.camOffset,
ref m_CamOffsetVelocity, 1);
if (s_Selected.mode == Mode.Activate)
{
// this is for a particle system that just needs activating, and needs no interaction (eg, duststorm)
return;
}
if (CheckForGuiCollision()) return;
bool oneShotClick = (Input.GetMouseButtonDown(0) && s_Selected.mode == Mode.Instantiate);
bool repeat = (Input.GetMouseButton(0) && s_Selected.mode == Mode.Trail);
if (oneShotClick || repeat)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
var rot = Quaternion.LookRotation(hit.normal);
if (s_Selected.align == AlignMode.Up)
{
rot = Quaternion.identity;
}
var pos = hit.point + hit.normal*spawnOffset;
if ((pos - m_LastPos).magnitude > s_Selected.minDist)
{
if (s_Selected.mode != Mode.Trail || m_Instance == null)
{
m_Instance = (Transform) Instantiate(s_Selected.transform, pos, rot);
if (m_ParticleMultiplier != null)
{
float multiply1 = multiply;
m_Instance.GetComponent<ParticleSystemMultiplier>().multiplier = multiply1;
}
m_CurrentParticleList.Add(m_Instance);
if (s_Selected.maxCount > 0 && m_CurrentParticleList.Count > s_Selected.maxCount)
{
if (m_CurrentParticleList[0] != null)
{
Destroy(m_CurrentParticleList[0].gameObject);
}
m_CurrentParticleList.RemoveAt(0);
}
}
else
{
m_Instance.position = pos;
m_Instance.rotation = rot;
}
if (s_Selected.mode == Mode.Trail)
{
var emission = m_Instance.transform.GetComponent<ParticleSystem>().emission;
emission.enabled = false;
m_Instance.transform.GetComponent<ParticleSystem>().Emit(1);
}
m_Instance.parent = hit.transform;
m_LastPos = pos;
}
}
}
}
#if !MOBILE_INPUT
void KeyboardInput()
{
if(Input.GetKeyDown(KeyCode.LeftArrow))
Previous();
if (Input.GetKeyDown(KeyCode.RightArrow))
Next();
}
#endif
bool CheckForGuiCollision()
{
PointerEventData eventData = new PointerEventData(eventSystem);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List<RaycastResult> list = new List<RaycastResult>();
graphicRaycaster.Raycast(eventData, list);
return list.Count > 0;
}
private void Select(int i)
{
s_Selected = demoParticles.items[i];
m_Instance = null;
foreach (var otherEffect in demoParticles.items)
{
if ((otherEffect != s_Selected) && (otherEffect.mode == Mode.Activate))
{
otherEffect.transform.gameObject.SetActive(false);
}
}
if (s_Selected.mode == Mode.Activate)
{
s_Selected.transform.gameObject.SetActive(true);
}
m_ParticleMultiplier = s_Selected.transform.GetComponent<ParticleSystemMultiplier>();
multiply = 1;
if (clearOnChange)
{
while (m_CurrentParticleList.Count > 0)
{
Destroy(m_CurrentParticleList[0].gameObject);
m_CurrentParticleList.RemoveAt(0);
}
}
instructionText.text = s_Selected.instructionText;
titleText.text = s_Selected.transform.name;
}
[Serializable]
public class DemoParticleSystem
{
public Transform transform;
public Mode mode;
public AlignMode align;
public int maxCount;
public float minDist;
public int camOffset = 15;
public string instructionText;
}
[Serializable]
public class DemoParticleSystemList
{
public DemoParticleSystem[] items;
}
}
}
//terrainのサイズを変更し、空間のサイズを規定する
Terrainのサイズがcubeなどの大きさに対して、異常に大きいのでサイズ変更する。
変更方法はterrainのインスペクター内部にある歯車マークをクリックし、mesh resolutionの中のwidthとlengthで変更できる。
初期では1000で設定されている。
ちなみに、このterrainの上にcubeオブジェクトをrotationをfreezeさせた状態で落下させたら、着地後にもオブジェクトが勝手に動いてしまう現象が見られた。
freeze rotationはしなくてよく、着地のバウンドをなくそうとするなら動作はゆっくりになるがdragの値を大きくすると最初に接触した場所から動くことはなくなる。