I have a situation where I need to allocate people to several events. If we just had a price as a factor, it would be fine, but there is a number of factors that come in.
This is a scheduling/optimisation problem, so the key question is "what quantity are you trying to maximise"? I'd guess you are looking to maximise the total number of hours worked across all your volunteers without clashes, subject to each volunteer's timetabling constraints. You also mention prioritising volunteers with more experience, so it sounds like you are saying "some volunteers are preferred over others".
This is then a classic bipartite matching problem. See e.g. p.498 of The Algorithm Design Manual (2nd ed.), by Steven Skiena. The basic approach is to construct a graph with vertices representing both the set of volunteers, and the set of time slots you are trying to fill. Edges link volunteers to valid time slots. The optimum solution is then the largest possible set of edges where no volunteer or time slot is repeated. This is a matching.
Some of your volunteers may be able to do more than one slot; this can be modeled by replicating that volunteer vertex multiple times.
If you want to implement the prioritising of volunteers, then this effectively adds a weighting to each edge, modeling the experience of that volunteer for that task. In this case, as you thought, you will need something like the Hungarian algorithm. If you can get away without this, then you can transform the problem into an equivalent flow graph, and apply a network flow algorithm. Here is one example of code that implements both weighted and unweighted matching.
If you want more details, including other alternatives, and more links to implementations, I do strongly recommend getting yourself a copy of the Algorithm Design Manual - it is an amazingly clear and practical reference.